@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.
Files changed (34) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +6 -0
  3. package/THIRD_PARTY_NOTICES.md +20 -0
  4. package/extension-contract.json +31 -0
  5. package/package.json +49 -0
  6. package/runtime/share/licenses/pgtap/README.md +153 -0
  7. package/runtime/share/postgresql/extension/pgtap--0.90.0--0.91.0.sql +29 -0
  8. package/runtime/share/postgresql/extension/pgtap--0.91.0--0.92.0.sql +1650 -0
  9. package/runtime/share/postgresql/extension/pgtap--0.92.0--0.93.0.sql +679 -0
  10. package/runtime/share/postgresql/extension/pgtap--0.93.0--0.94.0.sql +193 -0
  11. package/runtime/share/postgresql/extension/pgtap--0.94.0--0.95.0.sql +639 -0
  12. package/runtime/share/postgresql/extension/pgtap--0.95.0--0.96.0.sql +415 -0
  13. package/runtime/share/postgresql/extension/pgtap--0.96.0--0.97.0.sql +375 -0
  14. package/runtime/share/postgresql/extension/pgtap--0.97.0--0.98.0.sql +441 -0
  15. package/runtime/share/postgresql/extension/pgtap--0.98.0--0.99.0.sql +209 -0
  16. package/runtime/share/postgresql/extension/pgtap--0.99.0--1.0.0.sql +737 -0
  17. package/runtime/share/postgresql/extension/pgtap--1.0.0--1.1.0.sql +186 -0
  18. package/runtime/share/postgresql/extension/pgtap--1.1.0--1.2.0.sql +889 -0
  19. package/runtime/share/postgresql/extension/pgtap--1.2.0--1.3.0.sql +495 -0
  20. package/runtime/share/postgresql/extension/pgtap--1.3.0--1.3.1.sql +229 -0
  21. package/runtime/share/postgresql/extension/pgtap--1.3.1--1.3.2.sql +34 -0
  22. package/runtime/share/postgresql/extension/pgtap--1.3.2--1.3.3.sql +42 -0
  23. package/runtime/share/postgresql/extension/pgtap--1.3.3--1.3.4.sql +89 -0
  24. package/runtime/share/postgresql/extension/pgtap--1.3.4--1.3.5.sql +1 -0
  25. package/runtime/share/postgresql/extension/pgtap--1.3.5.sql +11520 -0
  26. package/runtime/share/postgresql/extension/pgtap--unpackaged--0.91.0.sql +714 -0
  27. package/runtime/share/postgresql/extension/pgtap-core--1.3.5.sql +4390 -0
  28. package/runtime/share/postgresql/extension/pgtap-core.sql +4390 -0
  29. package/runtime/share/postgresql/extension/pgtap-schema--1.3.5.sql +6764 -0
  30. package/runtime/share/postgresql/extension/pgtap-schema.sql +6764 -0
  31. package/runtime/share/postgresql/extension/pgtap.control +6 -0
  32. package/runtime/share/postgresql/extension/pgtap.sql +11520 -0
  33. package/runtime/share/postgresql/extension/uninstall_pgtap.sql +1088 -0
  34. package/share/licenses/pgtap/README.md +153 -0
@@ -0,0 +1,737 @@
1
+ CREATE OR REPLACE FUNCTION pgtap_version()
2
+ RETURNS NUMERIC AS 'SELECT 1.0;'
3
+ LANGUAGE SQL IMMUTABLE;
4
+
5
+ CREATE OR REPLACE FUNCTION _array_to_sorted_string( name[], text )
6
+ RETURNS text AS $$
7
+ SELECT array_to_string(ARRAY(
8
+ SELECT $1[i]
9
+ FROM generate_series(1, array_upper($1, 1)) s(i)
10
+ ORDER BY $1[i]
11
+ ), $2);
12
+ $$ LANGUAGE SQL immutable;
13
+
14
+ -- policies_are( schema, table, policies[], description )
15
+ CREATE OR REPLACE FUNCTION policies_are( NAME, NAME, NAME[], TEXT )
16
+ RETURNS TEXT AS $$
17
+ SELECT _are(
18
+ 'policies',
19
+ ARRAY(
20
+ SELECT p.polname
21
+ FROM pg_catalog.pg_policy p
22
+ JOIN pg_catalog.pg_class c ON c.oid = p.polrelid
23
+ JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
24
+ WHERE n.nspname = $1
25
+ AND c.relname = $2
26
+ EXCEPT
27
+ SELECT $3[i]
28
+ FROM generate_series(1, array_upper($3, 1)) s(i)
29
+ ),
30
+ ARRAY(
31
+ SELECT $3[i]
32
+ FROM generate_series(1, array_upper($3, 1)) s(i)
33
+ EXCEPT
34
+ SELECT p.polname
35
+ FROM pg_catalog.pg_policy p
36
+ JOIN pg_catalog.pg_class c ON c.oid = p.polrelid
37
+ JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
38
+ WHERE n.nspname = $1
39
+ AND c.relname = $2
40
+ ),
41
+ $4
42
+ );
43
+ $$ LANGUAGE SQL;
44
+
45
+ -- policies_are( schema, table, policies[] )
46
+ CREATE OR REPLACE FUNCTION policies_are( NAME, NAME, NAME[] )
47
+ RETURNS TEXT AS $$
48
+ SELECT policies_are( $1, $2, $3, 'Table ' || quote_ident($1) || '.' || quote_ident($2) || ' should have the correct policies' );
49
+ $$ LANGUAGE SQL;
50
+
51
+ -- policies_are( table, policies[], description )
52
+ CREATE OR REPLACE FUNCTION policies_are( NAME, NAME[], TEXT )
53
+ RETURNS TEXT AS $$
54
+ SELECT _are(
55
+ 'policies',
56
+ ARRAY(
57
+ SELECT p.polname
58
+ FROM pg_catalog.pg_policy p
59
+ JOIN pg_catalog.pg_class c ON c.oid = p.polrelid
60
+ JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
61
+ WHERE c.relname = $1
62
+ AND n.nspname NOT IN ('pg_catalog', 'information_schema')
63
+ EXCEPT
64
+ SELECT $2[i]
65
+ FROM generate_series(1, array_upper($2, 1)) s(i)
66
+ ),
67
+ ARRAY(
68
+ SELECT $2[i]
69
+ FROM generate_series(1, array_upper($2, 1)) s(i)
70
+ EXCEPT
71
+ SELECT p.polname
72
+ FROM pg_catalog.pg_policy p
73
+ JOIN pg_catalog.pg_class c ON c.oid = p.polrelid
74
+ JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
75
+ AND n.nspname NOT IN ('pg_catalog', 'information_schema')
76
+ ),
77
+ $3
78
+ );
79
+ $$ LANGUAGE SQL;
80
+
81
+ -- policies_are( table, policies[] )
82
+ CREATE OR REPLACE FUNCTION policies_are( NAME, NAME[] )
83
+ RETURNS TEXT AS $$
84
+ SELECT policies_are( $1, $2, 'Table ' || quote_ident($1) || ' should have the correct policies' );
85
+ $$ LANGUAGE SQL;
86
+
87
+ -- policy_roles_are( schema, table, policy, roles[], description )
88
+ CREATE OR REPLACE FUNCTION policy_roles_are( NAME, NAME, NAME, NAME[], TEXT )
89
+ RETURNS TEXT AS $$
90
+ SELECT _are(
91
+ 'policy roles',
92
+ ARRAY(
93
+ SELECT pr.rolname
94
+ FROM pg_catalog.pg_policy AS pp
95
+ JOIN pg_catalog.pg_roles AS pr ON pr.oid = ANY (pp.polroles)
96
+ JOIN pg_catalog.pg_class AS pc ON pc.oid = pp.polrelid
97
+ JOIN pg_catalog.pg_namespace AS pn ON pn.oid = pc.relnamespace
98
+ WHERE pn.nspname = $1
99
+ AND pc.relname = $2
100
+ AND pp.polname = $3
101
+ EXCEPT
102
+ SELECT $4[i]
103
+ FROM generate_series(1, array_upper($4, 1)) s(i)
104
+ ),
105
+ ARRAY(
106
+ SELECT $4[i]
107
+ FROM generate_series(1, array_upper($4, 1)) s(i)
108
+ EXCEPT
109
+ SELECT pr.rolname
110
+ FROM pg_catalog.pg_policy AS pp
111
+ JOIN pg_catalog.pg_roles AS pr ON pr.oid = ANY (pp.polroles)
112
+ JOIN pg_catalog.pg_class AS pc ON pc.oid = pp.polrelid
113
+ JOIN pg_catalog.pg_namespace AS pn ON pn.oid = pc.relnamespace
114
+ WHERE pn.nspname = $1
115
+ AND pc.relname = $2
116
+ AND pp.polname = $3
117
+ ),
118
+ $5
119
+ );
120
+ $$ LANGUAGE SQL;
121
+
122
+ -- policy_roles_are( schema, table, policy, roles[] )
123
+ CREATE OR REPLACE FUNCTION policy_roles_are( NAME, NAME, NAME, NAME[] )
124
+ RETURNS TEXT AS $$
125
+ SELECT policy_roles_are( $1, $2, $3, $4, 'Policy ' || quote_ident($3) || ' for table ' || quote_ident($1) || '.' || quote_ident($2) || ' should have the correct roles' );
126
+ $$ LANGUAGE SQL;
127
+
128
+ -- policy_roles_are( table, policy, roles[], description )
129
+ CREATE OR REPLACE FUNCTION policy_roles_are( NAME, NAME, NAME[], TEXT )
130
+ RETURNS TEXT AS $$
131
+ SELECT _are(
132
+ 'policy roles',
133
+ ARRAY(
134
+ SELECT pr.rolname
135
+ FROM pg_catalog.pg_policy AS pp
136
+ JOIN pg_catalog.pg_roles AS pr ON pr.oid = ANY (pp.polroles)
137
+ JOIN pg_catalog.pg_class AS pc ON pc.oid = pp.polrelid
138
+ JOIN pg_catalog.pg_namespace AS pn ON pn.oid = pc.relnamespace
139
+ WHERE pc.relname = $1
140
+ AND pp.polname = $2
141
+ AND pn.nspname NOT IN ('pg_catalog', 'information_schema')
142
+ EXCEPT
143
+ SELECT $3[i]
144
+ FROM generate_series(1, array_upper($3, 1)) s(i)
145
+ ),
146
+ ARRAY(
147
+ SELECT $3[i]
148
+ FROM generate_series(1, array_upper($3, 1)) s(i)
149
+ EXCEPT
150
+ SELECT pr.rolname
151
+ FROM pg_catalog.pg_policy AS pp
152
+ JOIN pg_catalog.pg_roles AS pr ON pr.oid = ANY (pp.polroles)
153
+ JOIN pg_catalog.pg_class AS pc ON pc.oid = pp.polrelid
154
+ JOIN pg_catalog.pg_namespace AS pn ON pn.oid = pc.relnamespace
155
+ WHERE pc.relname = $1
156
+ AND pp.polname = $2
157
+ AND pn.nspname NOT IN ('pg_catalog', 'information_schema')
158
+ ),
159
+ $4
160
+ );
161
+ $$ LANGUAGE SQL;
162
+
163
+ -- policy_roles_are( table, policy, roles[] )
164
+ CREATE OR REPLACE FUNCTION policy_roles_are( NAME, NAME, NAME[] )
165
+ RETURNS TEXT AS $$
166
+ SELECT policy_roles_are( $1, $2, $3, 'Policy ' || quote_ident($2) || ' for table ' || quote_ident($1) || ' should have the correct roles' );
167
+ $$ LANGUAGE SQL;
168
+
169
+ -- policy_cmd_is( schema, table, policy, command, description )
170
+ CREATE OR REPLACE FUNCTION policy_cmd_is( NAME, NAME, NAME, text, text )
171
+ RETURNS TEXT AS $$
172
+ DECLARE
173
+ cmd text;
174
+ BEGIN
175
+ SELECT
176
+ CASE pp.polcmd WHEN 'r' THEN 'SELECT'
177
+ WHEN 'a' THEN 'INSERT'
178
+ WHEN 'w' THEN 'UPDATE'
179
+ WHEN 'd' THEN 'DELETE'
180
+ ELSE 'ALL'
181
+ END
182
+ FROM pg_catalog.pg_policy AS pp
183
+ JOIN pg_catalog.pg_class AS pc ON pc.oid = pp.polrelid
184
+ JOIN pg_catalog.pg_namespace AS pn ON pn.oid = pc.relnamespace
185
+ WHERE pn.nspname = $1
186
+ AND pc.relname = $2
187
+ AND pp.polname = $3
188
+ INTO cmd;
189
+
190
+ RETURN is( cmd, upper($4), $5 );
191
+ END;
192
+ $$ LANGUAGE plpgsql;
193
+
194
+ -- policy_cmd_is( schema, table, policy, command )
195
+ CREATE OR REPLACE FUNCTION policy_cmd_is( NAME, NAME, NAME, text )
196
+ RETURNS TEXT AS $$
197
+ SELECT policy_cmd_is(
198
+ $1, $2, $3, $4,
199
+ 'Policy ' || quote_ident($3)
200
+ || ' for table ' || quote_ident($1) || '.' || quote_ident($2)
201
+ || ' should apply to ' || upper($4) || ' command'
202
+ );
203
+ $$ LANGUAGE sql;
204
+
205
+ -- policy_cmd_is( table, policy, command, description )
206
+ CREATE OR REPLACE FUNCTION policy_cmd_is( NAME, NAME, text, text )
207
+ RETURNS TEXT AS $$
208
+ DECLARE
209
+ cmd text;
210
+ BEGIN
211
+ SELECT
212
+ CASE pp.polcmd WHEN 'r' THEN 'SELECT'
213
+ WHEN 'a' THEN 'INSERT'
214
+ WHEN 'w' THEN 'UPDATE'
215
+ WHEN 'd' THEN 'DELETE'
216
+ ELSE 'ALL'
217
+ END
218
+ FROM pg_catalog.pg_policy AS pp
219
+ JOIN pg_catalog.pg_class AS pc ON pc.oid = pp.polrelid
220
+ JOIN pg_catalog.pg_namespace AS pn ON pn.oid = pc.relnamespace
221
+ WHERE pc.relname = $1
222
+ AND pp.polname = $2
223
+ AND pn.nspname NOT IN ('pg_catalog', 'information_schema')
224
+ INTO cmd;
225
+
226
+ RETURN is( cmd, upper($3), $4 );
227
+ END;
228
+ $$ LANGUAGE plpgsql;
229
+
230
+ -- policy_cmd_is( table, policy, command )
231
+ CREATE OR REPLACE FUNCTION policy_cmd_is( NAME, NAME, text )
232
+ RETURNS TEXT AS $$
233
+ SELECT policy_cmd_is(
234
+ $1, $2, $3,
235
+ 'Policy ' || quote_ident($2)
236
+ || ' for table ' || quote_ident($1)
237
+ || ' should apply to ' || upper($3) || ' command'
238
+ );
239
+ $$ LANGUAGE sql;
240
+
241
+ CREATE OR REPLACE FUNCTION _funkargs ( NAME[] )
242
+ RETURNS TEXT AS $$
243
+ BEGIN
244
+ RETURN array_to_string($1::regtype[], ',');
245
+ EXCEPTION WHEN undefined_object THEN
246
+ RETURN array_to_string($1, ',');
247
+ END;
248
+ $$ LANGUAGE PLPGSQL STABLE;
249
+
250
+ CREATE OR REPLACE FUNCTION _got_func ( NAME, NAME, NAME[] )
251
+ RETURNS BOOLEAN AS $$
252
+ SELECT EXISTS(
253
+ SELECT TRUE
254
+ FROM tap_funky
255
+ WHERE schema = $1
256
+ AND name = $2
257
+ AND args = _funkargs($3)
258
+ );
259
+ $$ LANGUAGE SQL;
260
+
261
+ CREATE OR REPLACE FUNCTION _got_func ( NAME, NAME[] )
262
+ RETURNS BOOLEAN AS $$
263
+ SELECT EXISTS(
264
+ SELECT TRUE
265
+ FROM tap_funky
266
+ WHERE name = $1
267
+ AND args = _funkargs($2)
268
+ AND is_visible
269
+ );
270
+ $$ LANGUAGE SQL;
271
+
272
+ /*
273
+ * Internal function to test whether the specified table in the specified schema
274
+ * has an inheritance chain. Returns true or false.
275
+ */
276
+ CREATE OR REPLACE FUNCTION _inherited( NAME, NAME )
277
+ RETURNS BOOLEAN AS $$
278
+ SELECT EXISTS(
279
+ SELECT true
280
+ FROM pg_catalog.pg_namespace n
281
+ JOIN pg_catalog.pg_class c ON n.oid = c.relnamespace
282
+ WHERE c.relkind = 'r'
283
+ AND n.nspname = $1
284
+ AND c.relname = $2
285
+ AND c.relhassubclass = true
286
+ );
287
+ $$ LANGUAGE SQL;
288
+
289
+ /*
290
+ * Internal function to test whether a specific table in the search_path has an
291
+ * inheritance chain. Returns true or false.
292
+ */
293
+ CREATE OR REPLACE FUNCTION _inherited( NAME )
294
+ RETURNS BOOLEAN AS $$
295
+ SELECT EXISTS(
296
+ SELECT true
297
+ FROM pg_catalog.pg_class c
298
+ WHERE c.relkind = 'r'
299
+ AND pg_catalog.pg_table_is_visible( c.oid )
300
+ AND c.relname = $1
301
+ AND c.relhassubclass = true
302
+ );
303
+ $$ LANGUAGE SQL;
304
+
305
+ -- has_inherited_tables( schema, table, description )
306
+ CREATE OR REPLACE FUNCTION has_inherited_tables( NAME, NAME, TEXT )
307
+ RETURNS TEXT AS $$
308
+ SELECT ok( _inherited( $1, $2 ), $3);
309
+ $$ LANGUAGE SQL;
310
+
311
+ -- has_inherited_tables( schema, table )
312
+ CREATE OR REPLACE FUNCTION has_inherited_tables( NAME, NAME )
313
+ RETURNS TEXT AS $$
314
+ SELECT ok(
315
+ _inherited( $1, $2 ),
316
+ 'Table ' || quote_ident( $1 ) || '.' || quote_ident( $2 ) || ' should have descendents'
317
+ );
318
+ $$ LANGUAGE SQL;
319
+
320
+ -- has_inherited_tables( table, description )
321
+ CREATE OR REPLACE FUNCTION has_inherited_tables( NAME, TEXT )
322
+ RETURNS TEXT AS $$
323
+ SELECT ok( _inherited( $1 ), $2 );
324
+ $$ LANGUAGE SQL;
325
+
326
+ -- has_inherited_tables( table )
327
+ CREATE OR REPLACE FUNCTION has_inherited_tables( NAME )
328
+ RETURNS TEXT AS $$
329
+ SELECT ok(
330
+ _inherited( $1 ),
331
+ 'Table ' || quote_ident( $1 ) || ' should have descendents'
332
+ );
333
+ $$ LANGUAGE SQL;
334
+
335
+ -- hasnt_inherited_tables( schema, table, description )
336
+ CREATE OR REPLACE FUNCTION hasnt_inherited_tables( NAME, NAME, TEXT )
337
+ RETURNS TEXT AS $$
338
+ SELECT ok( NOT _inherited( $1, $2 ), $3 );
339
+ $$ LANGUAGE SQL;
340
+
341
+ -- hasnt_inherited_tables( schema, table )
342
+ CREATE OR REPLACE FUNCTION hasnt_inherited_tables( NAME, NAME )
343
+ RETURNS TEXT AS $$
344
+ SELECT ok(
345
+ NOT _inherited( $1, $2 ),
346
+ 'Table ' || quote_ident( $1 ) || '.' || quote_ident( $2 ) || ' should not have descendents'
347
+ );
348
+ $$ LANGUAGE SQL;
349
+
350
+ -- hasnt_inherited_tables( table, description )
351
+ CREATE OR REPLACE FUNCTION hasnt_inherited_tables( NAME, TEXT )
352
+ RETURNS TEXT AS $$
353
+ SELECT ok( NOT _inherited( $1 ), $2 );
354
+ $$ LANGUAGE SQL;
355
+
356
+ -- hasnt_inherited_tables( table )
357
+ CREATE OR REPLACE FUNCTION hasnt_inherited_tables( NAME )
358
+ RETURNS TEXT AS $$
359
+ SELECT ok(
360
+ NOT _inherited( $1 ),
361
+ 'Table ' || quote_ident( $1 ) || ' should not have descendents'
362
+ );
363
+ $$ LANGUAGE SQL;
364
+
365
+ /*
366
+ * Internal function to test whether the schema-qualified table is an ancestor of
367
+ * the other schema-qualified table. The integer value is the length of the
368
+ * inheritance chain: a direct ancestor has has a chain length of 1.
369
+ */
370
+ CREATE OR REPLACE FUNCTION _ancestor_of( NAME, NAME, NAME, NAME, INT )
371
+ RETURNS BOOLEAN AS $$
372
+ WITH RECURSIVE inheritance_chain AS (
373
+ -- select the ancestor tuple
374
+ SELECT i.inhrelid AS descendent_id, 1 AS inheritance_level
375
+ FROM pg_catalog.pg_inherits i
376
+ WHERE i.inhparent = (
377
+ SELECT c1.oid
378
+ FROM pg_catalog.pg_class c1
379
+ JOIN pg_catalog.pg_namespace n1
380
+ ON c1.relnamespace = n1.oid
381
+ WHERE c1.relname = $2
382
+ AND n1.nspname = $1
383
+ )
384
+ UNION
385
+ -- select the descendents
386
+ SELECT i.inhrelid AS descendent_id,
387
+ p.inheritance_level + 1 AS inheritance_level
388
+ FROM pg_catalog.pg_inherits i
389
+ JOIN inheritance_chain p
390
+ ON p.descendent_id = i.inhparent
391
+ WHERE i.inhrelid = (
392
+ SELECT c1.oid
393
+ FROM pg_catalog.pg_class c1
394
+ JOIN pg_catalog.pg_namespace n1
395
+ ON c1.relnamespace = n1.oid
396
+ WHERE c1.relname = $4
397
+ AND n1.nspname = $3
398
+ )
399
+ )
400
+ SELECT EXISTS(
401
+ SELECT true
402
+ FROM inheritance_chain
403
+ WHERE inheritance_level = COALESCE($5, inheritance_level)
404
+ AND descendent_id = (
405
+ SELECT c1.oid
406
+ FROM pg_catalog.pg_class c1
407
+ JOIN pg_catalog.pg_namespace n1
408
+ ON c1.relnamespace = n1.oid
409
+ WHERE c1.relname = $4
410
+ AND n1.nspname = $3
411
+ )
412
+ );
413
+ $$ LANGUAGE SQL;
414
+
415
+ /*
416
+ * Internal function to check if not-qualified tables
417
+ * within the search_path are connected by an inheritance chain.
418
+ */
419
+ CREATE OR REPLACE FUNCTION _ancestor_of( NAME, NAME, INT )
420
+ RETURNS BOOLEAN AS $$
421
+ WITH RECURSIVE inheritance_chain AS (
422
+ -- select the ancestor tuple
423
+ SELECT i.inhrelid AS descendent_id, 1 AS inheritance_level
424
+ FROM pg_catalog.pg_inherits i
425
+ WHERE i.inhparent = (
426
+ SELECT c1.oid
427
+ FROM pg_catalog.pg_class c1
428
+ JOIN pg_catalog.pg_namespace n1
429
+ ON c1.relnamespace = n1.oid
430
+ WHERE c1.relname = $1
431
+ AND pg_catalog.pg_table_is_visible( c1.oid )
432
+ )
433
+ UNION
434
+ -- select the descendents
435
+ SELECT i.inhrelid AS descendent_id,
436
+ p.inheritance_level + 1 AS inheritance_level
437
+ FROM pg_catalog.pg_inherits i
438
+ JOIN inheritance_chain p
439
+ ON p.descendent_id = i.inhparent
440
+ WHERE i.inhrelid = (
441
+ SELECT c1.oid
442
+ FROM pg_catalog.pg_class c1
443
+ JOIN pg_catalog.pg_namespace n1
444
+ ON c1.relnamespace = n1.oid
445
+ WHERE c1.relname = $2
446
+ AND pg_catalog.pg_table_is_visible( c1.oid )
447
+ )
448
+ )
449
+ SELECT EXISTS(
450
+ SELECT true
451
+ FROM inheritance_chain
452
+ WHERE inheritance_level = COALESCE($3, inheritance_level)
453
+ AND descendent_id = (
454
+ SELECT c1.oid
455
+ FROM pg_catalog.pg_class c1
456
+ JOIN pg_catalog.pg_namespace n1
457
+ ON c1.relnamespace = n1.oid
458
+ WHERE c1.relname = $2
459
+ AND pg_catalog.pg_table_is_visible( c1.oid )
460
+ )
461
+ );
462
+ $$ LANGUAGE SQL;
463
+
464
+ -- is_ancestor_of( schema, table, schema, table, depth, description )
465
+ CREATE OR REPLACE FUNCTION is_ancestor_of( NAME, NAME, NAME, NAME, INT, TEXT )
466
+ RETURNS TEXT AS $$
467
+ SELECT ok( _ancestor_of( $1, $2, $3, $4, $5 ), $6 );
468
+ $$ LANGUAGE SQL;
469
+
470
+ -- is_ancestor_of( schema, table, schema, table, depth )
471
+ CREATE OR REPLACE FUNCTION is_ancestor_of( NAME, NAME, NAME, NAME, INT )
472
+ RETURNS TEXT AS $$
473
+ SELECT ok(
474
+ _ancestor_of( $1, $2, $3, $4, $5 ),
475
+ 'Table ' || quote_ident( $1 ) || '.' || quote_ident( $2 )
476
+ || ' should be ancestor ' || $5 || ' for '
477
+ || quote_ident( $3 ) || '.' || quote_ident( $4 )
478
+ );
479
+ $$ LANGUAGE SQL;
480
+
481
+ -- is_ancestor_of( schema, table, schema, table, description )
482
+ CREATE OR REPLACE FUNCTION is_ancestor_of( NAME, NAME, NAME, NAME, TEXT )
483
+ RETURNS TEXT AS $$
484
+ SELECT ok( _ancestor_of( $1, $2, $3, $4, NULL ), $5 );
485
+ $$ LANGUAGE SQL;
486
+
487
+ -- is_ancestor_of( schema, table, schema, table )
488
+ CREATE OR REPLACE FUNCTION is_ancestor_of( NAME, NAME, NAME, NAME )
489
+ RETURNS TEXT AS $$
490
+ SELECT ok(
491
+ _ancestor_of( $1, $2, $3, $4, NULL ),
492
+ 'Table ' || quote_ident( $1 ) || '.' || quote_ident( $2 )
493
+ || ' should be an ancestor of '
494
+ || quote_ident( $3 ) || '.' || quote_ident( $4 )
495
+ );
496
+ $$ LANGUAGE SQL;
497
+
498
+ -- is_ancestor_of( table, table, depth, description )
499
+ CREATE OR REPLACE FUNCTION is_ancestor_of( NAME, NAME, INT, TEXT )
500
+ RETURNS TEXT AS $$
501
+ SELECT ok( _ancestor_of( $1, $2, $3 ), $4 );
502
+ $$ LANGUAGE SQL;
503
+
504
+ -- is_ancestor_of( table, table, depth )
505
+ CREATE OR REPLACE FUNCTION is_ancestor_of( NAME, NAME, INT )
506
+ RETURNS TEXT AS $$
507
+ SELECT ok(
508
+ _ancestor_of( $1, $2, $3 ),
509
+ 'Table ' || quote_ident( $1 ) || ' should be ancestor ' || $3 || ' of ' || quote_ident( $2)
510
+ );
511
+ $$ LANGUAGE SQL;
512
+
513
+ -- is_ancestor_of( table, table, description )
514
+ CREATE OR REPLACE FUNCTION is_ancestor_of( NAME, NAME, TEXT )
515
+ RETURNS TEXT AS $$
516
+ SELECT ok( _ancestor_of( $1, $2, NULL ), $3 );
517
+ $$ LANGUAGE SQL;
518
+
519
+ -- is_ancestor_of( table, table )
520
+ CREATE OR REPLACE FUNCTION is_ancestor_of( NAME, NAME )
521
+ RETURNS TEXT AS $$
522
+ SELECT ok(
523
+ _ancestor_of( $1, $2, NULL ),
524
+ 'Table ' || quote_ident( $1 ) || ' should be an ancestor of ' || quote_ident( $2)
525
+ );
526
+ $$ LANGUAGE SQL;
527
+
528
+ -- isnt_ancestor_of( schema, table, schema, table, depth, description )
529
+ CREATE OR REPLACE FUNCTION isnt_ancestor_of( NAME, NAME, NAME, NAME, INT, TEXT )
530
+ RETURNS TEXT AS $$
531
+ SELECT ok( NOT _ancestor_of( $1, $2, $3, $4, $5 ), $6 );
532
+ $$ LANGUAGE SQL;
533
+
534
+ -- isnt_ancestor_of( schema, table, schema, table, depth )
535
+ CREATE OR REPLACE FUNCTION isnt_ancestor_of( NAME, NAME, NAME, NAME, INT )
536
+ RETURNS TEXT AS $$
537
+ SELECT ok(
538
+ NOT _ancestor_of( $1, $2, $3, $4, $5 ),
539
+ 'Table ' || quote_ident( $1 ) || '.' || quote_ident( $2 )
540
+ || ' should not be ancestor ' || $5 || ' for '
541
+ || quote_ident( $3 ) || '.' || quote_ident( $4 )
542
+ );
543
+ $$ LANGUAGE SQL;
544
+
545
+ -- isnt_ancestor_of( schema, table, schema, table, description )
546
+ CREATE OR REPLACE FUNCTION isnt_ancestor_of( NAME, NAME, NAME, NAME, TEXT )
547
+ RETURNS TEXT AS $$
548
+ SELECT ok( NOT _ancestor_of( $1, $2, $3, $4, NULL ), $5 );
549
+ $$ LANGUAGE SQL;
550
+
551
+ -- isnt_ancestor_of( schema, table, schema, table )
552
+ CREATE OR REPLACE FUNCTION isnt_ancestor_of( NAME, NAME, NAME, NAME )
553
+ RETURNS TEXT AS $$
554
+ SELECT ok(
555
+ NOT _ancestor_of( $1, $2, $3, $4, NULL ),
556
+ 'Table ' || quote_ident( $1 ) || '.' || quote_ident( $2 )
557
+ || ' should not be an ancestor of '
558
+ || quote_ident( $3 ) || '.' || quote_ident( $4 )
559
+ );
560
+ $$ LANGUAGE SQL;
561
+
562
+ -- isnt_ancestor_of( table, table, depth, description )
563
+ CREATE OR REPLACE FUNCTION isnt_ancestor_of( NAME, NAME, INT, TEXT )
564
+ RETURNS TEXT AS $$
565
+ SELECT ok( NOT _ancestor_of( $1, $2, $3 ), $4 );
566
+ $$ LANGUAGE SQL;
567
+
568
+ -- isnt_ancestor_of( table, table, depth )
569
+ CREATE OR REPLACE FUNCTION isnt_ancestor_of( NAME, NAME, INT )
570
+ RETURNS TEXT AS $$
571
+ SELECT ok(
572
+ NOT _ancestor_of( $1, $2, $3 ),
573
+ 'Table ' || quote_ident( $1 ) || ' should not be ancestor ' || $3 || ' of ' || quote_ident( $2)
574
+ );
575
+ $$ LANGUAGE SQL;
576
+
577
+ -- isnt_ancestor_of( table, table, description )
578
+ CREATE OR REPLACE FUNCTION isnt_ancestor_of( NAME, NAME, TEXT )
579
+ RETURNS TEXT AS $$
580
+ SELECT ok( NOT _ancestor_of( $1, $2, NULL ), $3 );
581
+ $$ LANGUAGE SQL;
582
+
583
+ -- isnt_ancestor_of( table, table )
584
+ CREATE OR REPLACE FUNCTION isnt_ancestor_of( NAME, NAME )
585
+ RETURNS TEXT AS $$
586
+ SELECT ok(
587
+ NOT _ancestor_of( $1, $2, NULL ),
588
+ 'Table ' || quote_ident( $1 ) || ' should not be an ancestor of ' || quote_ident( $2)
589
+ );
590
+ $$ LANGUAGE SQL;
591
+
592
+ -- is_descendent_of( schema, table, schema, table, depth, description )
593
+ CREATE OR REPLACE FUNCTION is_descendent_of( NAME, NAME, NAME, NAME, INT, TEXT )
594
+ RETURNS TEXT AS $$
595
+ SELECT ok( _ancestor_of( $3, $4, $1, $2, $5 ), $6 );
596
+ $$ LANGUAGE SQL;
597
+
598
+ -- is_descendent_of( schema, table, schema, table, depth )
599
+ CREATE OR REPLACE FUNCTION is_descendent_of( NAME, NAME, NAME, NAME, INT )
600
+ RETURNS TEXT AS $$
601
+ SELECT ok(
602
+ _ancestor_of( $3, $4, $1, $2, $5 ),
603
+ 'Table ' || quote_ident( $1 ) || '.' || quote_ident( $2 )
604
+ || ' should be descendent ' || $5 || ' from '
605
+ || quote_ident( $3 ) || '.' || quote_ident( $4 )
606
+ );
607
+ $$ LANGUAGE SQL;
608
+
609
+ -- is_descendent_of( schema, table, schema, table, description )
610
+ CREATE OR REPLACE FUNCTION is_descendent_of( NAME, NAME, NAME, NAME, TEXT )
611
+ RETURNS TEXT AS $$
612
+ SELECT ok( _ancestor_of( $3, $4, $1, $2, NULL ), $5 );
613
+ $$ LANGUAGE SQL;
614
+
615
+ -- is_descendent_of( schema, table, schema, table )
616
+ CREATE OR REPLACE FUNCTION is_descendent_of( NAME, NAME, NAME, NAME )
617
+ RETURNS TEXT AS $$
618
+ SELECT ok(
619
+ _ancestor_of( $3, $4, $1, $2, NULL ),
620
+ 'Table ' || quote_ident( $1 ) || '.' || quote_ident( $2 )
621
+ || ' should be a descendent of '
622
+ || quote_ident( $3 ) || '.' || quote_ident( $4 )
623
+ );
624
+ $$ LANGUAGE SQL;
625
+
626
+ -- is_descendent_of( table, table, depth, description )
627
+ CREATE OR REPLACE FUNCTION is_descendent_of( NAME, NAME, INT, TEXT )
628
+ RETURNS TEXT AS $$
629
+ SELECT ok( _ancestor_of( $2, $1, $3 ), $4 );
630
+ $$ LANGUAGE SQL;
631
+
632
+ -- is_descendent_of( table, table, depth )
633
+ CREATE OR REPLACE FUNCTION is_descendent_of( NAME, NAME, INT )
634
+ RETURNS TEXT AS $$
635
+ SELECT ok(
636
+ _ancestor_of( $2, $1, $3 ),
637
+ 'Table ' || quote_ident( $1 ) || ' should be descendent ' || $3 || ' from ' || quote_ident( $2)
638
+ );
639
+ $$ LANGUAGE SQL;
640
+
641
+ -- is_descendent_of( table, table, description )
642
+ CREATE OR REPLACE FUNCTION is_descendent_of( NAME, NAME, TEXT )
643
+ RETURNS TEXT AS $$
644
+ SELECT ok( _ancestor_of( $2, $1, NULL ), $3 );
645
+ $$ LANGUAGE SQL;
646
+
647
+ -- is_descendent_of( table, table )
648
+ CREATE OR REPLACE FUNCTION is_descendent_of( NAME, NAME )
649
+ RETURNS TEXT AS $$
650
+ SELECT ok(
651
+ _ancestor_of( $2, $1, NULL ),
652
+ 'Table ' || quote_ident( $1 ) || ' should be a descendent of ' || quote_ident( $2)
653
+ );
654
+ $$ LANGUAGE SQL;
655
+
656
+ -- isnt_descendent_of( schema, table, schema, table, depth, description )
657
+ CREATE OR REPLACE FUNCTION isnt_descendent_of( NAME, NAME, NAME, NAME, INT, TEXT )
658
+ RETURNS TEXT AS $$
659
+ SELECT ok(NOT _ancestor_of( $3, $4, $1, $2, $5 ), $6 );
660
+ $$ LANGUAGE SQL;
661
+
662
+ -- isnt_descendent_of( schema, table, schema, table, depth )
663
+ CREATE OR REPLACE FUNCTION isnt_descendent_of( NAME, NAME, NAME, NAME, INT )
664
+ RETURNS TEXT AS $$
665
+ SELECT ok(
666
+ NOT _ancestor_of( $3, $4, $1, $2, $5 ),
667
+ 'Table ' || quote_ident( $1 ) || '.' || quote_ident( $2 )
668
+ || ' should not be descendent ' || $5 || ' from '
669
+ || quote_ident( $3 ) || '.' || quote_ident( $4 )
670
+ );
671
+ $$ LANGUAGE SQL;
672
+
673
+ -- isnt_descendent_of( schema, table, schema, table, description )
674
+ CREATE OR REPLACE FUNCTION isnt_descendent_of( NAME, NAME, NAME, NAME, TEXT )
675
+ RETURNS TEXT AS $$
676
+ SELECT ok(NOT _ancestor_of( $3, $4, $1, $2, NULL ), $5 );
677
+ $$ LANGUAGE SQL;
678
+
679
+ -- isnt_descendent_of( schema, table, schema, table )
680
+ CREATE OR REPLACE FUNCTION isnt_descendent_of( NAME, NAME, NAME, NAME )
681
+ RETURNS TEXT AS $$
682
+ SELECT ok(
683
+ NOT _ancestor_of( $3, $4, $1, $2, NULL ),
684
+ 'Table ' || quote_ident( $1 ) || '.' || quote_ident( $2 )
685
+ || ' should not be a descendent of '
686
+ || quote_ident( $3 ) || '.' || quote_ident( $4 )
687
+ );
688
+ $$ LANGUAGE SQL;
689
+
690
+ -- isnt_descendent_of( table, table, depth, description )
691
+ CREATE OR REPLACE FUNCTION isnt_descendent_of( NAME, NAME, INT, TEXT )
692
+ RETURNS TEXT AS $$
693
+ SELECT ok(NOT _ancestor_of( $2, $1, $3 ), $4 );
694
+ $$ LANGUAGE SQL;
695
+
696
+ -- isnt_descendent_of( table, table, depth )
697
+ CREATE OR REPLACE FUNCTION isnt_descendent_of( NAME, NAME, INT )
698
+ RETURNS TEXT AS $$
699
+ SELECT ok(
700
+ NOT _ancestor_of( $2, $1, $3 ),
701
+ 'Table ' || quote_ident( $1 ) || ' should not be descendent ' || $3 || ' from ' || quote_ident( $2)
702
+ );
703
+ $$ LANGUAGE SQL;
704
+
705
+ -- isnt_descendent_of( table, table, description )
706
+ CREATE OR REPLACE FUNCTION isnt_descendent_of( NAME, NAME, TEXT )
707
+ RETURNS TEXT AS $$
708
+ SELECT ok(NOT _ancestor_of( $2, $1, NULL ), $3 );
709
+ $$ LANGUAGE SQL;
710
+
711
+ -- isnt_descendent_of( table, table )
712
+ CREATE OR REPLACE FUNCTION isnt_descendent_of( NAME, NAME )
713
+ RETURNS TEXT AS $$
714
+ SELECT ok(
715
+ NOT _ancestor_of( $2, $1, NULL ),
716
+ 'Table ' || quote_ident( $1 ) || ' should not be a descendent of ' || quote_ident( $2)
717
+ );
718
+ $$ LANGUAGE SQL;
719
+
720
+ CREATE OR REPLACE FUNCTION _def_is( TEXT, TEXT, anyelement, TEXT )
721
+ RETURNS TEXT AS $$
722
+ DECLARE
723
+ thing text;
724
+ BEGIN
725
+ -- Function or special SQL syntax.
726
+ IF $1 ~ '^[^'']+[(]' OR $1 = ANY('{CURRENT_CATALOG,CURRENT_ROLE,CURRENT_SCHEMA,CURRENT_USER,SESSION_USER,USER}') THEN
727
+ RETURN is( $1, $3, $4 );
728
+ END IF;
729
+
730
+ EXECUTE 'SELECT is('
731
+ || COALESCE($1, 'NULL' || '::' || $2) || '::' || $2 || ', '
732
+ || COALESCE(quote_literal($3), 'NULL') || '::' || $2 || ', '
733
+ || COALESCE(quote_literal($4), 'NULL')
734
+ || ')' INTO thing;
735
+ RETURN thing;
736
+ END;
737
+ $$ LANGUAGE plpgsql;