@oliphaunt/extension-pgtap-linux-arm64-gnu 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +6 -0
- package/THIRD_PARTY_NOTICES.md +20 -0
- package/extension-contract.json +31 -0
- package/package.json +49 -0
- package/runtime/share/licenses/pgtap/README.md +153 -0
- package/runtime/share/postgresql/extension/pgtap--0.90.0--0.91.0.sql +29 -0
- package/runtime/share/postgresql/extension/pgtap--0.91.0--0.92.0.sql +1650 -0
- package/runtime/share/postgresql/extension/pgtap--0.92.0--0.93.0.sql +679 -0
- package/runtime/share/postgresql/extension/pgtap--0.93.0--0.94.0.sql +193 -0
- package/runtime/share/postgresql/extension/pgtap--0.94.0--0.95.0.sql +639 -0
- package/runtime/share/postgresql/extension/pgtap--0.95.0--0.96.0.sql +415 -0
- package/runtime/share/postgresql/extension/pgtap--0.96.0--0.97.0.sql +375 -0
- package/runtime/share/postgresql/extension/pgtap--0.97.0--0.98.0.sql +441 -0
- package/runtime/share/postgresql/extension/pgtap--0.98.0--0.99.0.sql +209 -0
- package/runtime/share/postgresql/extension/pgtap--0.99.0--1.0.0.sql +737 -0
- package/runtime/share/postgresql/extension/pgtap--1.0.0--1.1.0.sql +186 -0
- package/runtime/share/postgresql/extension/pgtap--1.1.0--1.2.0.sql +889 -0
- package/runtime/share/postgresql/extension/pgtap--1.2.0--1.3.0.sql +495 -0
- package/runtime/share/postgresql/extension/pgtap--1.3.0--1.3.1.sql +229 -0
- package/runtime/share/postgresql/extension/pgtap--1.3.1--1.3.2.sql +34 -0
- package/runtime/share/postgresql/extension/pgtap--1.3.2--1.3.3.sql +42 -0
- package/runtime/share/postgresql/extension/pgtap--1.3.3--1.3.4.sql +89 -0
- package/runtime/share/postgresql/extension/pgtap--1.3.4--1.3.5.sql +1 -0
- package/runtime/share/postgresql/extension/pgtap--1.3.5.sql +11520 -0
- package/runtime/share/postgresql/extension/pgtap--unpackaged--0.91.0.sql +714 -0
- package/runtime/share/postgresql/extension/pgtap-core--1.3.5.sql +4390 -0
- package/runtime/share/postgresql/extension/pgtap-core.sql +4390 -0
- package/runtime/share/postgresql/extension/pgtap-schema--1.3.5.sql +6764 -0
- package/runtime/share/postgresql/extension/pgtap-schema.sql +6764 -0
- package/runtime/share/postgresql/extension/pgtap.control +6 -0
- package/runtime/share/postgresql/extension/pgtap.sql +11520 -0
- package/runtime/share/postgresql/extension/uninstall_pgtap.sql +1088 -0
- package/share/licenses/pgtap/README.md +153 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
-- Use DO to ignore failures when the shared library doesn't exist, because it
|
|
2
|
+
-- only existed for 1.3.1, and if upgrades are running from a later release it
|
|
3
|
+
-- won't be there.
|
|
4
|
+
DO $$
|
|
5
|
+
BEGIN
|
|
6
|
+
CREATE FUNCTION parse_type(type text, OUT typid oid, OUT typmod int4)
|
|
7
|
+
RETURNS RECORD
|
|
8
|
+
AS 'pgtap'
|
|
9
|
+
LANGUAGE C STABLE STRICT;
|
|
10
|
+
EXCEPTION
|
|
11
|
+
WHEN undefined_file THEN
|
|
12
|
+
RAISE NOTICE 'No pgtap shared library; skipping C parse_type()';
|
|
13
|
+
END;
|
|
14
|
+
$$;
|
|
15
|
+
|
|
16
|
+
CREATE OR REPLACE FUNCTION format_type_string ( TEXT )
|
|
17
|
+
RETURNS TEXT AS $$
|
|
18
|
+
BEGIN RETURN format_type(p.typid, p.typmod) from parse_type($1) p;
|
|
19
|
+
EXCEPTION WHEN OTHERS THEN RETURN NULL;
|
|
20
|
+
END;
|
|
21
|
+
$$ LANGUAGE PLPGSQL STABLE;
|
|
22
|
+
|
|
23
|
+
-- col_type_is( schema, table, column, schema, type, description )
|
|
24
|
+
CREATE OR REPLACE FUNCTION col_type_is ( NAME, NAME, NAME, NAME, TEXT, TEXT )
|
|
25
|
+
RETURNS TEXT AS $$
|
|
26
|
+
DECLARE
|
|
27
|
+
have_type TEXT := _get_col_ns_type($1, $2, $3);
|
|
28
|
+
want_type TEXT;
|
|
29
|
+
BEGIN
|
|
30
|
+
IF have_type IS NULL THEN
|
|
31
|
+
RETURN fail( $6 ) || E'\n' || diag (
|
|
32
|
+
' Column ' || COALESCE(quote_ident($1) || '.', '')
|
|
33
|
+
|| quote_ident($2) || '.' || quote_ident($3) || ' does not exist'
|
|
34
|
+
);
|
|
35
|
+
END IF;
|
|
36
|
+
|
|
37
|
+
IF quote_ident($4) = ANY(current_schemas(true)) THEN
|
|
38
|
+
want_type := quote_ident($4) || '.' || format_type_string($5);
|
|
39
|
+
ELSE
|
|
40
|
+
want_type := format_type_string(quote_ident($4) || '.' || $5);
|
|
41
|
+
END IF;
|
|
42
|
+
|
|
43
|
+
IF want_type IS NULL THEN
|
|
44
|
+
RETURN fail( $6 ) || E'\n' || diag (
|
|
45
|
+
' Type ' || quote_ident($4) || '.' || $5 || ' does not exist'
|
|
46
|
+
);
|
|
47
|
+
END IF;
|
|
48
|
+
|
|
49
|
+
IF have_type = want_type THEN
|
|
50
|
+
-- We're good to go.
|
|
51
|
+
RETURN ok( true, $6 );
|
|
52
|
+
END IF;
|
|
53
|
+
|
|
54
|
+
-- Wrong data type. tell 'em what we really got.
|
|
55
|
+
RETURN ok( false, $6 ) || E'\n' || diag(
|
|
56
|
+
' have: ' || have_type ||
|
|
57
|
+
E'\n want: ' || want_type
|
|
58
|
+
);
|
|
59
|
+
END;
|
|
60
|
+
$$ LANGUAGE plpgsql;
|
|
61
|
+
|
|
62
|
+
-- col_type_is( schema, table, column, schema, type )
|
|
63
|
+
CREATE OR REPLACE FUNCTION col_type_is ( NAME, NAME, NAME, NAME, TEXT )
|
|
64
|
+
RETURNS TEXT AS $$
|
|
65
|
+
SELECT col_type_is( $1, $2, $3, $4, $5, 'Column ' || quote_ident($1) || '.' || quote_ident($2)
|
|
66
|
+
|| '.' || quote_ident($3) || ' should be type ' || quote_ident($4) || '.' || $5);
|
|
67
|
+
$$ LANGUAGE SQL;
|
|
68
|
+
|
|
69
|
+
-- col_type_is( schema, table, column, type, description )
|
|
70
|
+
CREATE OR REPLACE FUNCTION col_type_is ( NAME, NAME, NAME, TEXT, TEXT )
|
|
71
|
+
RETURNS TEXT AS $$
|
|
72
|
+
DECLARE
|
|
73
|
+
have_type TEXT;
|
|
74
|
+
want_type TEXT;
|
|
75
|
+
BEGIN
|
|
76
|
+
-- Get the data type.
|
|
77
|
+
IF $1 IS NULL THEN
|
|
78
|
+
have_type := _get_col_type($2, $3);
|
|
79
|
+
ELSE
|
|
80
|
+
have_type := _get_col_type($1, $2, $3);
|
|
81
|
+
END IF;
|
|
82
|
+
|
|
83
|
+
IF have_type IS NULL THEN
|
|
84
|
+
RETURN fail( $5 ) || E'\n' || diag (
|
|
85
|
+
' Column ' || COALESCE(quote_ident($1) || '.', '')
|
|
86
|
+
|| quote_ident($2) || '.' || quote_ident($3) || ' does not exist'
|
|
87
|
+
);
|
|
88
|
+
END IF;
|
|
89
|
+
|
|
90
|
+
want_type := format_type_string($4);
|
|
91
|
+
IF want_type IS NULL THEN
|
|
92
|
+
RETURN fail( $5 ) || E'\n' || diag (
|
|
93
|
+
' Type ' || $4 || ' does not exist'
|
|
94
|
+
);
|
|
95
|
+
END IF;
|
|
96
|
+
|
|
97
|
+
IF have_type = want_type THEN
|
|
98
|
+
-- We're good to go.
|
|
99
|
+
RETURN ok( true, $5 );
|
|
100
|
+
END IF;
|
|
101
|
+
|
|
102
|
+
-- Wrong data type. tell 'em what we really got.
|
|
103
|
+
RETURN ok( false, $5 ) || E'\n' || diag(
|
|
104
|
+
' have: ' || have_type ||
|
|
105
|
+
E'\n want: ' || want_type
|
|
106
|
+
);
|
|
107
|
+
END;
|
|
108
|
+
$$ LANGUAGE plpgsql;
|
|
109
|
+
|
|
110
|
+
CREATE OR REPLACE FUNCTION _cmp_types(oid, name)
|
|
111
|
+
RETURNS BOOLEAN AS $$
|
|
112
|
+
SELECT pg_catalog.format_type($1, NULL) = _typename($2);
|
|
113
|
+
$$ LANGUAGE sql;
|
|
114
|
+
|
|
115
|
+
-- domain_type_is( schema, domain, schema, type, description )
|
|
116
|
+
CREATE OR REPLACE FUNCTION domain_type_is( NAME, TEXT, NAME, TEXT, TEXT )
|
|
117
|
+
RETURNS TEXT AS $$
|
|
118
|
+
DECLARE
|
|
119
|
+
actual_type TEXT := _get_dtype($1, $2, true);
|
|
120
|
+
BEGIN
|
|
121
|
+
IF actual_type IS NULL THEN
|
|
122
|
+
RETURN fail( $5 ) || E'\n' || diag (
|
|
123
|
+
' Domain ' || quote_ident($1) || '.' || $2
|
|
124
|
+
|| ' does not exist'
|
|
125
|
+
);
|
|
126
|
+
END IF;
|
|
127
|
+
|
|
128
|
+
IF quote_ident($3) = ANY(current_schemas(true)) THEN
|
|
129
|
+
RETURN is( actual_type, quote_ident($3) || '.' || _typename($4), $5);
|
|
130
|
+
END IF;
|
|
131
|
+
RETURN is( actual_type, _typename(quote_ident($3) || '.' || $4), $5);
|
|
132
|
+
END;
|
|
133
|
+
$$ LANGUAGE plpgsql;
|
|
134
|
+
|
|
135
|
+
-- domain_type_is( schema, domain, type, description )
|
|
136
|
+
CREATE OR REPLACE FUNCTION domain_type_is( NAME, TEXT, TEXT, TEXT )
|
|
137
|
+
RETURNS TEXT AS $$
|
|
138
|
+
DECLARE
|
|
139
|
+
actual_type TEXT := _get_dtype($1, $2, false);
|
|
140
|
+
BEGIN
|
|
141
|
+
IF actual_type IS NULL THEN
|
|
142
|
+
RETURN fail( $4 ) || E'\n' || diag (
|
|
143
|
+
' Domain ' || quote_ident($1) || '.' || $2
|
|
144
|
+
|| ' does not exist'
|
|
145
|
+
);
|
|
146
|
+
END IF;
|
|
147
|
+
|
|
148
|
+
RETURN is( actual_type, _typename($3), $4 );
|
|
149
|
+
END;
|
|
150
|
+
$$ LANGUAGE plpgsql;
|
|
151
|
+
|
|
152
|
+
-- domain_type_is( domain, type, description )
|
|
153
|
+
CREATE OR REPLACE FUNCTION domain_type_is( TEXT, TEXT, TEXT )
|
|
154
|
+
RETURNS TEXT AS $$
|
|
155
|
+
DECLARE
|
|
156
|
+
actual_type TEXT := _get_dtype($1);
|
|
157
|
+
BEGIN
|
|
158
|
+
IF actual_type IS NULL THEN
|
|
159
|
+
RETURN fail( $3 ) || E'\n' || diag (
|
|
160
|
+
' Domain ' || $1 || ' does not exist'
|
|
161
|
+
);
|
|
162
|
+
END IF;
|
|
163
|
+
|
|
164
|
+
RETURN is( actual_type, _typename($2), $3 );
|
|
165
|
+
END;
|
|
166
|
+
$$ LANGUAGE plpgsql;
|
|
167
|
+
|
|
168
|
+
-- domain_type_isnt( schema, domain, schema, type, description )
|
|
169
|
+
CREATE OR REPLACE FUNCTION domain_type_isnt( NAME, TEXT, NAME, TEXT, TEXT )
|
|
170
|
+
RETURNS TEXT AS $$
|
|
171
|
+
DECLARE
|
|
172
|
+
actual_type TEXT := _get_dtype($1, $2, true);
|
|
173
|
+
BEGIN
|
|
174
|
+
IF actual_type IS NULL THEN
|
|
175
|
+
RETURN fail( $5 ) || E'\n' || diag (
|
|
176
|
+
' Domain ' || quote_ident($1) || '.' || $2
|
|
177
|
+
|| ' does not exist'
|
|
178
|
+
);
|
|
179
|
+
END IF;
|
|
180
|
+
|
|
181
|
+
IF quote_ident($3) = ANY(current_schemas(true)) THEN
|
|
182
|
+
RETURN isnt( actual_type, quote_ident($3) || '.' || _typename($4), $5);
|
|
183
|
+
END IF;
|
|
184
|
+
RETURN isnt( actual_type, _typename(quote_ident($3) || '.' || $4), $5);
|
|
185
|
+
END;
|
|
186
|
+
$$ LANGUAGE plpgsql;
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
-- domain_type_isnt( schema, domain, type, description )
|
|
190
|
+
CREATE OR REPLACE FUNCTION domain_type_isnt( NAME, TEXT, TEXT, TEXT )
|
|
191
|
+
RETURNS TEXT AS $$
|
|
192
|
+
DECLARE
|
|
193
|
+
actual_type TEXT := _get_dtype($1, $2, false);
|
|
194
|
+
BEGIN
|
|
195
|
+
IF actual_type IS NULL THEN
|
|
196
|
+
RETURN fail( $4 ) || E'\n' || diag (
|
|
197
|
+
' Domain ' || quote_ident($1) || '.' || $2
|
|
198
|
+
|| ' does not exist'
|
|
199
|
+
);
|
|
200
|
+
END IF;
|
|
201
|
+
|
|
202
|
+
RETURN isnt( actual_type, _typename($3), $4 );
|
|
203
|
+
END;
|
|
204
|
+
$$ LANGUAGE plpgsql;
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
-- domain_type_isnt( domain, type, description )
|
|
208
|
+
CREATE OR REPLACE FUNCTION domain_type_isnt( TEXT, TEXT, TEXT )
|
|
209
|
+
RETURNS TEXT AS $$
|
|
210
|
+
DECLARE
|
|
211
|
+
actual_type TEXT := _get_dtype($1);
|
|
212
|
+
BEGIN
|
|
213
|
+
IF actual_type IS NULL THEN
|
|
214
|
+
RETURN fail( $3 ) || E'\n' || diag (
|
|
215
|
+
' Domain ' || $1 || ' does not exist'
|
|
216
|
+
);
|
|
217
|
+
END IF;
|
|
218
|
+
|
|
219
|
+
RETURN isnt( actual_type, _typename($2), $3 );
|
|
220
|
+
END;
|
|
221
|
+
$$ LANGUAGE plpgsql;
|
|
222
|
+
|
|
223
|
+
DROP FUNCTION _quote_ident_like(TEXT, TEXT);
|
|
224
|
+
|
|
225
|
+
-- has_pk( schema, table )
|
|
226
|
+
CREATE OR REPLACE FUNCTION has_pk ( NAME, NAME )
|
|
227
|
+
RETURNS TEXT AS $$
|
|
228
|
+
SELECT has_pk( $1, $2, 'Table ' || quote_ident($1) || '.' || quote_ident($2) || ' should have a primary key' );
|
|
229
|
+
$$ LANGUAGE sql;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
DROP FUNCTION IF EXISTS parse_type(type text, OUT typid oid, OUT typmod int4);
|
|
2
|
+
|
|
3
|
+
CREATE OR REPLACE FUNCTION format_type_string ( TEXT )
|
|
4
|
+
RETURNS TEXT AS $$
|
|
5
|
+
DECLARE
|
|
6
|
+
want_type TEXT := $1;
|
|
7
|
+
typmodin_arg cstring[];
|
|
8
|
+
typmodin_func regproc;
|
|
9
|
+
typmod int;
|
|
10
|
+
BEGIN
|
|
11
|
+
IF want_type::regtype = 'interval'::regtype THEN
|
|
12
|
+
-- RAISE NOTICE 'cannot resolve: %', want_type; -- TODO
|
|
13
|
+
RETURN want_type;
|
|
14
|
+
END IF;
|
|
15
|
+
|
|
16
|
+
-- Extract type modifier from type declaration and format as cstring[] literal.
|
|
17
|
+
typmodin_arg := translate(substring(want_type FROM '[(][^")]+[)]'), '()', '{}');
|
|
18
|
+
|
|
19
|
+
-- Find typmodin function for want_type.
|
|
20
|
+
SELECT typmodin INTO typmodin_func
|
|
21
|
+
FROM pg_catalog.pg_type
|
|
22
|
+
WHERE oid = want_type::regtype;
|
|
23
|
+
|
|
24
|
+
IF typmodin_func = 0 THEN
|
|
25
|
+
-- Easy: types without typemods.
|
|
26
|
+
RETURN format_type(want_type::regtype, null);
|
|
27
|
+
END IF;
|
|
28
|
+
|
|
29
|
+
-- Get typemod via type-specific typmodin function.
|
|
30
|
+
EXECUTE format('SELECT %I(%L)', typmodin_func, typmodin_arg) INTO typmod;
|
|
31
|
+
RETURN format_type(want_type::regtype, typmod);
|
|
32
|
+
EXCEPTION WHEN OTHERS THEN RETURN NULL;
|
|
33
|
+
END;
|
|
34
|
+
$$ LANGUAGE PLPGSQL STABLE;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
CREATE OR REPLACE FUNCTION format_type_string ( TEXT )
|
|
2
|
+
RETURNS TEXT AS $$
|
|
3
|
+
DECLARE
|
|
4
|
+
want_type TEXT := $1;
|
|
5
|
+
BEGIN
|
|
6
|
+
IF pg_version_num() >= 170000 THEN
|
|
7
|
+
-- to_regtypemod() in 17 allows easy and corret normalization.
|
|
8
|
+
RETURN format_type(to_regtype(want_type), to_regtypemod(want_type));
|
|
9
|
+
END IF;
|
|
10
|
+
|
|
11
|
+
IF want_type::regtype = 'interval'::regtype THEN
|
|
12
|
+
-- We cannot normlize interval types without to_regtypemod(), So
|
|
13
|
+
-- just return it as is.
|
|
14
|
+
RETURN want_type;
|
|
15
|
+
END IF;
|
|
16
|
+
|
|
17
|
+
-- Use the typmodin functions to correctly normalize types.
|
|
18
|
+
DECLARE
|
|
19
|
+
typmodin_arg cstring[];
|
|
20
|
+
typmodin_func regproc;
|
|
21
|
+
typmod int;
|
|
22
|
+
BEGIN
|
|
23
|
+
-- Extract type modifier from type declaration and format as cstring[] literal.
|
|
24
|
+
typmodin_arg := translate(substring(want_type FROM '[(][^")]+[)]'), '()', '{}');
|
|
25
|
+
|
|
26
|
+
-- Find typmodin function for want_type.
|
|
27
|
+
SELECT typmodin INTO typmodin_func
|
|
28
|
+
FROM pg_catalog.pg_type
|
|
29
|
+
WHERE oid = want_type::regtype;
|
|
30
|
+
|
|
31
|
+
IF typmodin_func = 0 THEN
|
|
32
|
+
-- Easy: types without typemods.
|
|
33
|
+
RETURN format_type(want_type::regtype, null);
|
|
34
|
+
END IF;
|
|
35
|
+
|
|
36
|
+
-- Get typemod via type-specific typmodin function.
|
|
37
|
+
EXECUTE format('SELECT %s(%L)', typmodin_func, typmodin_arg) INTO typmod;
|
|
38
|
+
RETURN format_type(want_type::regtype, typmod);
|
|
39
|
+
END;
|
|
40
|
+
EXCEPTION WHEN OTHERS THEN RETURN NULL;
|
|
41
|
+
END;
|
|
42
|
+
$$ LANGUAGE PLPGSQL STABLE;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
-- has_composite( schema, type )
|
|
2
|
+
CREATE OR REPLACE FUNCTION has_composite ( NAME, NAME )
|
|
3
|
+
RETURNS TEXT AS $$
|
|
4
|
+
SELECT has_composite(
|
|
5
|
+
$1, $2,
|
|
6
|
+
'Composite type ' || quote_ident($1) || '.' || quote_ident($2) || ' should exist'
|
|
7
|
+
);
|
|
8
|
+
$$ LANGUAGE SQL;
|
|
9
|
+
|
|
10
|
+
-- hasnt_composite( schema, type )
|
|
11
|
+
CREATE OR REPLACE FUNCTION hasnt_composite ( NAME, NAME )
|
|
12
|
+
RETURNS TEXT AS $$
|
|
13
|
+
SELECT hasnt_composite(
|
|
14
|
+
$1, $2,
|
|
15
|
+
'Composite type ' || quote_ident($1) || '.' || quote_ident($2) || ' should not exist'
|
|
16
|
+
);
|
|
17
|
+
$$ LANGUAGE SQL;
|
|
18
|
+
|
|
19
|
+
-- index_is_partial( schema, table, index, description )
|
|
20
|
+
CREATE OR REPLACE FUNCTION index_is_partial ( NAME, NAME, NAME, text )
|
|
21
|
+
RETURNS TEXT AS $$
|
|
22
|
+
DECLARE
|
|
23
|
+
res boolean;
|
|
24
|
+
BEGIN
|
|
25
|
+
SELECT x.indpred IS NOT NULL
|
|
26
|
+
FROM pg_catalog.pg_index x
|
|
27
|
+
JOIN pg_catalog.pg_class ct ON ct.oid = x.indrelid
|
|
28
|
+
JOIN pg_catalog.pg_class ci ON ci.oid = x.indexrelid
|
|
29
|
+
JOIN pg_catalog.pg_namespace n ON n.oid = ct.relnamespace
|
|
30
|
+
WHERE ct.relname = $2
|
|
31
|
+
AND ci.relname = $3
|
|
32
|
+
AND n.nspname = $1
|
|
33
|
+
INTO res;
|
|
34
|
+
|
|
35
|
+
RETURN ok( COALESCE(res, false), $4 );
|
|
36
|
+
END;
|
|
37
|
+
$$ LANGUAGE plpgsql;
|
|
38
|
+
|
|
39
|
+
-- index_is_partial( schema, table, index )
|
|
40
|
+
CREATE OR REPLACE FUNCTION index_is_partial ( NAME, NAME, NAME )
|
|
41
|
+
RETURNS TEXT AS $$
|
|
42
|
+
SELECT index_is_partial(
|
|
43
|
+
$1, $2, $3,
|
|
44
|
+
'Index ' || quote_ident($3) || ' should be partial'
|
|
45
|
+
);
|
|
46
|
+
$$ LANGUAGE sql;
|
|
47
|
+
|
|
48
|
+
-- index_is_partial( table, index )
|
|
49
|
+
CREATE OR REPLACE FUNCTION index_is_partial ( NAME, NAME )
|
|
50
|
+
RETURNS TEXT AS $$
|
|
51
|
+
DECLARE
|
|
52
|
+
res boolean;
|
|
53
|
+
BEGIN
|
|
54
|
+
SELECT x.indpred IS NOT NULL
|
|
55
|
+
FROM pg_catalog.pg_index x
|
|
56
|
+
JOIN pg_catalog.pg_class ct ON ct.oid = x.indrelid
|
|
57
|
+
JOIN pg_catalog.pg_class ci ON ci.oid = x.indexrelid
|
|
58
|
+
WHERE ct.relname = $1
|
|
59
|
+
AND ci.relname = $2
|
|
60
|
+
AND pg_catalog.pg_table_is_visible(ct.oid)
|
|
61
|
+
INTO res;
|
|
62
|
+
|
|
63
|
+
RETURN ok(
|
|
64
|
+
COALESCE(res, false),
|
|
65
|
+
'Index ' || quote_ident($2) || ' should be partial'
|
|
66
|
+
);
|
|
67
|
+
END;
|
|
68
|
+
$$ LANGUAGE plpgsql;
|
|
69
|
+
|
|
70
|
+
-- index_is_partial( index )
|
|
71
|
+
CREATE OR REPLACE FUNCTION index_is_partial ( NAME )
|
|
72
|
+
RETURNS TEXT AS $$
|
|
73
|
+
DECLARE
|
|
74
|
+
res boolean;
|
|
75
|
+
BEGIN
|
|
76
|
+
SELECT x.indpred IS NOT NULL
|
|
77
|
+
FROM pg_catalog.pg_index x
|
|
78
|
+
JOIN pg_catalog.pg_class ci ON ci.oid = x.indexrelid
|
|
79
|
+
JOIN pg_catalog.pg_class ct ON ct.oid = x.indrelid
|
|
80
|
+
WHERE ci.relname = $1
|
|
81
|
+
AND pg_catalog.pg_table_is_visible(ct.oid)
|
|
82
|
+
INTO res;
|
|
83
|
+
|
|
84
|
+
RETURN ok(
|
|
85
|
+
COALESCE(res, false),
|
|
86
|
+
'Index ' || quote_ident($1) || ' should be partial'
|
|
87
|
+
);
|
|
88
|
+
END;
|
|
89
|
+
$$ LANGUAGE plpgsql;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
-- Changes between pgTAP v1.3.4 and v1.3.5.
|