]> granicus.if.org Git - postgresql/blob - src/test/regress/expected/opr_sanity.out
Create a "sort support" interface API for faster sorting.
[postgresql] / src / test / regress / expected / opr_sanity.out
1 --
2 -- OPR_SANITY
3 -- Sanity checks for common errors in making operator/procedure system tables:
4 -- pg_operator, pg_proc, pg_cast, pg_aggregate, pg_am,
5 -- pg_amop, pg_amproc, pg_opclass, pg_opfamily.
6 --
7 -- None of the SELECTs here should ever find any matching entries,
8 -- so the expected output is easy to maintain ;-).
9 -- A test failure indicates someone messed up an entry in the system tables.
10 --
11 -- NB: we assume the oidjoins test will have caught any dangling links,
12 -- that is OID or REGPROC fields that are not zero and do not match some
13 -- row in the linked-to table.  However, if we want to enforce that a link
14 -- field can't be 0, we have to check it here.
15 --
16 -- NB: run this test earlier than the create_operator test, because
17 -- that test creates some bogus operators...
18 -- Helper functions to deal with cases where binary-coercible matches are
19 -- allowed.
20 -- This should match IsBinaryCoercible() in parse_coerce.c.
21 create function binary_coercible(oid, oid) returns bool as $$
22 SELECT ($1 = $2) OR
23  EXISTS(select 1 from pg_catalog.pg_cast where
24         castsource = $1 and casttarget = $2 and
25         castmethod = 'b' and castcontext = 'i') OR
26  ($2 = 'pg_catalog.anyarray'::pg_catalog.regtype AND
27   EXISTS(select 1 from pg_catalog.pg_type where
28          oid = $1 and typelem != 0 and typlen = -1))
29 $$ language sql strict stable;
30 -- This one ignores castcontext, so it considers only physical equivalence
31 -- and not whether the coercion can be invoked implicitly.
32 create function physically_coercible(oid, oid) returns bool as $$
33 SELECT ($1 = $2) OR
34  EXISTS(select 1 from pg_catalog.pg_cast where
35         castsource = $1 and casttarget = $2 and
36         castmethod = 'b') OR
37  ($2 = 'pg_catalog.anyarray'::pg_catalog.regtype AND
38   EXISTS(select 1 from pg_catalog.pg_type where
39          oid = $1 and typelem != 0 and typlen = -1))
40 $$ language sql strict stable;
41 -- **************** pg_proc ****************
42 -- Look for illegal values in pg_proc fields.
43 SELECT p1.oid, p1.proname
44 FROM pg_proc as p1
45 WHERE p1.prolang = 0 OR p1.prorettype = 0 OR
46        p1.pronargs < 0 OR
47        p1.pronargdefaults < 0 OR
48        p1.pronargdefaults > p1.pronargs OR
49        array_lower(p1.proargtypes, 1) != 0 OR
50        array_upper(p1.proargtypes, 1) != p1.pronargs-1 OR
51        0::oid = ANY (p1.proargtypes) OR
52        procost <= 0 OR
53        CASE WHEN proretset THEN prorows <= 0 ELSE prorows != 0 END;
54  oid | proname 
55 -----+---------
56 (0 rows)
57
58 -- prosrc should never be null or empty
59 SELECT p1.oid, p1.proname
60 FROM pg_proc as p1
61 WHERE prosrc IS NULL OR prosrc = '' OR prosrc = '-';
62  oid | proname 
63 -----+---------
64 (0 rows)
65
66 -- proiswindow shouldn't be set together with proisagg or proretset
67 SELECT p1.oid, p1.proname
68 FROM pg_proc AS p1
69 WHERE proiswindow AND (proisagg OR proretset);
70  oid | proname 
71 -----+---------
72 (0 rows)
73
74 -- pronargdefaults should be 0 iff proargdefaults is null
75 SELECT p1.oid, p1.proname
76 FROM pg_proc AS p1
77 WHERE (pronargdefaults <> 0) != (proargdefaults IS NOT NULL);
78  oid | proname 
79 -----+---------
80 (0 rows)
81
82 -- probin should be non-empty for C functions, null everywhere else
83 SELECT p1.oid, p1.proname
84 FROM pg_proc as p1
85 WHERE prolang = 13 AND (probin IS NULL OR probin = '' OR probin = '-');
86  oid | proname 
87 -----+---------
88 (0 rows)
89
90 SELECT p1.oid, p1.proname
91 FROM pg_proc as p1
92 WHERE prolang != 13 AND probin IS NOT NULL;
93  oid | proname 
94 -----+---------
95 (0 rows)
96
97 -- Look for conflicting proc definitions (same names and input datatypes).
98 -- (This test should be dead code now that we have the unique index
99 -- pg_proc_proname_args_nsp_index, but I'll leave it in anyway.)
100 SELECT p1.oid, p1.proname, p2.oid, p2.proname
101 FROM pg_proc AS p1, pg_proc AS p2
102 WHERE p1.oid != p2.oid AND
103     p1.proname = p2.proname AND
104     p1.pronargs = p2.pronargs AND
105     p1.proargtypes = p2.proargtypes;
106  oid | proname | oid | proname 
107 -----+---------+-----+---------
108 (0 rows)
109
110 -- Considering only built-in procs (prolang = 12), look for multiple uses
111 -- of the same internal function (ie, matching prosrc fields).  It's OK to
112 -- have several entries with different pronames for the same internal function,
113 -- but conflicts in the number of arguments and other critical items should
114 -- be complained of.  (We don't check data types here; see next query.)
115 -- Note: ignore aggregate functions here, since they all point to the same
116 -- dummy built-in function.
117 SELECT p1.oid, p1.proname, p2.oid, p2.proname
118 FROM pg_proc AS p1, pg_proc AS p2
119 WHERE p1.oid < p2.oid AND
120     p1.prosrc = p2.prosrc AND
121     p1.prolang = 12 AND p2.prolang = 12 AND
122     (p1.proisagg = false OR p2.proisagg = false) AND
123     (p1.prolang != p2.prolang OR
124      p1.proisagg != p2.proisagg OR
125      p1.prosecdef != p2.prosecdef OR
126      p1.proisstrict != p2.proisstrict OR
127      p1.proretset != p2.proretset OR
128      p1.provolatile != p2.provolatile OR
129      p1.pronargs != p2.pronargs);
130  oid | proname | oid | proname 
131 -----+---------+-----+---------
132 (0 rows)
133
134 -- Look for uses of different type OIDs in the argument/result type fields
135 -- for different aliases of the same built-in function.
136 -- This indicates that the types are being presumed to be binary-equivalent,
137 -- or that the built-in function is prepared to deal with different types.
138 -- That's not wrong, necessarily, but we make lists of all the types being
139 -- so treated.  Note that the expected output of this part of the test will
140 -- need to be modified whenever new pairs of types are made binary-equivalent,
141 -- or when new polymorphic built-in functions are added!
142 -- Note: ignore aggregate functions here, since they all point to the same
143 -- dummy built-in function.  Likewise, ignore range constructor functions.
144 SELECT DISTINCT p1.prorettype, p2.prorettype
145 FROM pg_proc AS p1, pg_proc AS p2
146 WHERE p1.oid != p2.oid AND
147     p1.prosrc = p2.prosrc AND
148     p1.prolang = 12 AND p2.prolang = 12 AND
149     NOT p1.proisagg AND NOT p2.proisagg AND
150     p1.prosrc NOT LIKE E'range\\_constructor_' AND
151     p2.prosrc NOT LIKE E'range\\_constructor_' AND
152     (p1.prorettype < p2.prorettype)
153 ORDER BY 1, 2;
154  prorettype | prorettype 
155 ------------+------------
156          25 |       1043
157        1114 |       1184
158 (2 rows)
159
160 SELECT DISTINCT p1.proargtypes[0], p2.proargtypes[0]
161 FROM pg_proc AS p1, pg_proc AS p2
162 WHERE p1.oid != p2.oid AND
163     p1.prosrc = p2.prosrc AND
164     p1.prolang = 12 AND p2.prolang = 12 AND
165     NOT p1.proisagg AND NOT p2.proisagg AND
166     p1.prosrc NOT LIKE E'range\\_constructor_' AND
167     p2.prosrc NOT LIKE E'range\\_constructor_' AND
168     (p1.proargtypes[0] < p2.proargtypes[0])
169 ORDER BY 1, 2;
170  proargtypes | proargtypes 
171 -------------+-------------
172           25 |        1042
173           25 |        1043
174         1114 |        1184
175         1560 |        1562
176         2277 |        2283
177 (5 rows)
178
179 SELECT DISTINCT p1.proargtypes[1], p2.proargtypes[1]
180 FROM pg_proc AS p1, pg_proc AS p2
181 WHERE p1.oid != p2.oid AND
182     p1.prosrc = p2.prosrc AND
183     p1.prolang = 12 AND p2.prolang = 12 AND
184     NOT p1.proisagg AND NOT p2.proisagg AND
185     p1.prosrc NOT LIKE E'range\\_constructor_' AND
186     p2.prosrc NOT LIKE E'range\\_constructor_' AND
187     (p1.proargtypes[1] < p2.proargtypes[1])
188 ORDER BY 1, 2;
189  proargtypes | proargtypes 
190 -------------+-------------
191           23 |          28
192         1114 |        1184
193         1560 |        1562
194         2277 |        2283
195 (4 rows)
196
197 SELECT DISTINCT p1.proargtypes[2], p2.proargtypes[2]
198 FROM pg_proc AS p1, pg_proc AS p2
199 WHERE p1.oid != p2.oid AND
200     p1.prosrc = p2.prosrc AND
201     p1.prolang = 12 AND p2.prolang = 12 AND
202     NOT p1.proisagg AND NOT p2.proisagg AND
203     (p1.proargtypes[2] < p2.proargtypes[2])
204 ORDER BY 1, 2;
205  proargtypes | proargtypes 
206 -------------+-------------
207         1114 |        1184
208 (1 row)
209
210 SELECT DISTINCT p1.proargtypes[3], p2.proargtypes[3]
211 FROM pg_proc AS p1, pg_proc AS p2
212 WHERE p1.oid != p2.oid AND
213     p1.prosrc = p2.prosrc AND
214     p1.prolang = 12 AND p2.prolang = 12 AND
215     NOT p1.proisagg AND NOT p2.proisagg AND
216     (p1.proargtypes[3] < p2.proargtypes[3])
217 ORDER BY 1, 2;
218  proargtypes | proargtypes 
219 -------------+-------------
220         1114 |        1184
221 (1 row)
222
223 SELECT DISTINCT p1.proargtypes[4], p2.proargtypes[4]
224 FROM pg_proc AS p1, pg_proc AS p2
225 WHERE p1.oid != p2.oid AND
226     p1.prosrc = p2.prosrc AND
227     p1.prolang = 12 AND p2.prolang = 12 AND
228     NOT p1.proisagg AND NOT p2.proisagg AND
229     (p1.proargtypes[4] < p2.proargtypes[4])
230 ORDER BY 1, 2;
231  proargtypes | proargtypes 
232 -------------+-------------
233 (0 rows)
234
235 SELECT DISTINCT p1.proargtypes[5], p2.proargtypes[5]
236 FROM pg_proc AS p1, pg_proc AS p2
237 WHERE p1.oid != p2.oid AND
238     p1.prosrc = p2.prosrc AND
239     p1.prolang = 12 AND p2.prolang = 12 AND
240     NOT p1.proisagg AND NOT p2.proisagg AND
241     (p1.proargtypes[5] < p2.proargtypes[5])
242 ORDER BY 1, 2;
243  proargtypes | proargtypes 
244 -------------+-------------
245 (0 rows)
246
247 SELECT DISTINCT p1.proargtypes[6], p2.proargtypes[6]
248 FROM pg_proc AS p1, pg_proc AS p2
249 WHERE p1.oid != p2.oid AND
250     p1.prosrc = p2.prosrc AND
251     p1.prolang = 12 AND p2.prolang = 12 AND
252     NOT p1.proisagg AND NOT p2.proisagg AND
253     (p1.proargtypes[6] < p2.proargtypes[6])
254 ORDER BY 1, 2;
255  proargtypes | proargtypes 
256 -------------+-------------
257 (0 rows)
258
259 SELECT DISTINCT p1.proargtypes[7], p2.proargtypes[7]
260 FROM pg_proc AS p1, pg_proc AS p2
261 WHERE p1.oid != p2.oid AND
262     p1.prosrc = p2.prosrc AND
263     p1.prolang = 12 AND p2.prolang = 12 AND
264     NOT p1.proisagg AND NOT p2.proisagg AND
265     (p1.proargtypes[7] < p2.proargtypes[7])
266 ORDER BY 1, 2;
267  proargtypes | proargtypes 
268 -------------+-------------
269 (0 rows)
270
271 -- Look for functions that return type "internal" and do not have any
272 -- "internal" argument.  Such a function would be a security hole since
273 -- it might be used to call an internal function from an SQL command.
274 -- As of 7.3 this query should find only internal_in.
275 SELECT p1.oid, p1.proname
276 FROM pg_proc as p1
277 WHERE p1.prorettype = 'internal'::regtype AND NOT
278     'internal'::regtype = ANY (p1.proargtypes);
279  oid  |   proname   
280 ------+-------------
281  2304 | internal_in
282 (1 row)
283
284 -- Check for length inconsistencies between the various argument-info arrays.
285 SELECT p1.oid, p1.proname
286 FROM pg_proc as p1
287 WHERE proallargtypes IS NOT NULL AND
288     array_length(proallargtypes,1) < array_length(proargtypes,1);
289  oid | proname 
290 -----+---------
291 (0 rows)
292
293 SELECT p1.oid, p1.proname
294 FROM pg_proc as p1
295 WHERE proargmodes IS NOT NULL AND
296     array_length(proargmodes,1) < array_length(proargtypes,1);
297  oid | proname 
298 -----+---------
299 (0 rows)
300
301 SELECT p1.oid, p1.proname
302 FROM pg_proc as p1
303 WHERE proargnames IS NOT NULL AND
304     array_length(proargnames,1) < array_length(proargtypes,1);
305  oid | proname 
306 -----+---------
307 (0 rows)
308
309 SELECT p1.oid, p1.proname
310 FROM pg_proc as p1
311 WHERE proallargtypes IS NOT NULL AND proargmodes IS NOT NULL AND
312     array_length(proallargtypes,1) <> array_length(proargmodes,1);
313  oid | proname 
314 -----+---------
315 (0 rows)
316
317 SELECT p1.oid, p1.proname
318 FROM pg_proc as p1
319 WHERE proallargtypes IS NOT NULL AND proargnames IS NOT NULL AND
320     array_length(proallargtypes,1) <> array_length(proargnames,1);
321  oid | proname 
322 -----+---------
323 (0 rows)
324
325 SELECT p1.oid, p1.proname
326 FROM pg_proc as p1
327 WHERE proargmodes IS NOT NULL AND proargnames IS NOT NULL AND
328     array_length(proargmodes,1) <> array_length(proargnames,1);
329  oid | proname 
330 -----+---------
331 (0 rows)
332
333 -- Insist that all built-in pg_proc entries have descriptions
334 SELECT p1.oid, p1.proname
335 FROM pg_proc as p1 LEFT JOIN pg_description as d
336      ON p1.tableoid = d.classoid and p1.oid = d.objoid and d.objsubid = 0
337 WHERE d.classoid IS NULL AND p1.oid <= 9999;
338  oid | proname 
339 -----+---------
340 (0 rows)
341
342 -- **************** pg_cast ****************
343 -- Catch bogus values in pg_cast columns (other than cases detected by
344 -- oidjoins test).
345 SELECT *
346 FROM pg_cast c
347 WHERE castsource = 0 OR casttarget = 0 OR castcontext NOT IN ('e', 'a', 'i')
348     OR castmethod NOT IN ('f', 'b' ,'i');
349  castsource | casttarget | castfunc | castcontext | castmethod 
350 ------------+------------+----------+-------------+------------
351 (0 rows)
352
353 -- Check that castfunc is nonzero only for cast methods that need a function,
354 -- and zero otherwise
355 SELECT *
356 FROM pg_cast c
357 WHERE (castmethod = 'f' AND castfunc = 0)
358    OR (castmethod IN ('b', 'i') AND castfunc <> 0);
359  castsource | casttarget | castfunc | castcontext | castmethod 
360 ------------+------------+----------+-------------+------------
361 (0 rows)
362
363 -- Look for casts to/from the same type that aren't length coercion functions.
364 -- (We assume they are length coercions if they take multiple arguments.)
365 -- Such entries are not necessarily harmful, but they are useless.
366 SELECT *
367 FROM pg_cast c
368 WHERE castsource = casttarget AND castfunc = 0;
369  castsource | casttarget | castfunc | castcontext | castmethod 
370 ------------+------------+----------+-------------+------------
371 (0 rows)
372
373 SELECT c.*
374 FROM pg_cast c, pg_proc p
375 WHERE c.castfunc = p.oid AND p.pronargs < 2 AND castsource = casttarget;
376  castsource | casttarget | castfunc | castcontext | castmethod 
377 ------------+------------+----------+-------------+------------
378 (0 rows)
379
380 -- Look for cast functions that don't have the right signature.  The
381 -- argument and result types in pg_proc must be the same as, or binary
382 -- compatible with, what it says in pg_cast.
383 -- As a special case, we allow casts from CHAR(n) that use functions
384 -- declared to take TEXT.  This does not pass the binary-coercibility test
385 -- because CHAR(n)-to-TEXT normally invokes rtrim().  However, the results
386 -- are the same, so long as the function is one that ignores trailing blanks.
387 SELECT c.*
388 FROM pg_cast c, pg_proc p
389 WHERE c.castfunc = p.oid AND
390     (p.pronargs < 1 OR p.pronargs > 3
391      OR NOT (binary_coercible(c.castsource, p.proargtypes[0])
392              OR (c.castsource = 'character'::regtype AND
393                  p.proargtypes[0] = 'text'::regtype))
394      OR NOT binary_coercible(p.prorettype, c.casttarget));
395  castsource | casttarget | castfunc | castcontext | castmethod 
396 ------------+------------+----------+-------------+------------
397 (0 rows)
398
399 SELECT c.*
400 FROM pg_cast c, pg_proc p
401 WHERE c.castfunc = p.oid AND
402     ((p.pronargs > 1 AND p.proargtypes[1] != 'int4'::regtype) OR
403      (p.pronargs > 2 AND p.proargtypes[2] != 'bool'::regtype));
404  castsource | casttarget | castfunc | castcontext | castmethod 
405 ------------+------------+----------+-------------+------------
406 (0 rows)
407
408 -- Look for binary compatible casts that do not have the reverse
409 -- direction registered as well, or where the reverse direction is not
410 -- also binary compatible.  This is legal, but usually not intended.
411 -- As of 7.4, this finds the casts from text and varchar to bpchar, because
412 -- those are binary-compatible while the reverse way goes through rtrim().
413 -- As of 8.2, this finds the cast from cidr to inet, because that is a
414 -- trivial binary coercion while the other way goes through inet_to_cidr().
415 -- As of 8.3, this finds the casts from xml to text, varchar, and bpchar,
416 -- because those are binary-compatible while the reverse goes through
417 -- texttoxml(), which does an XML syntax check.
418 -- As of 9.1, this finds the cast from pg_node_tree to text, which we
419 -- intentionally do not provide a reverse pathway for.
420 SELECT castsource::regtype, casttarget::regtype, castfunc, castcontext
421 FROM pg_cast c
422 WHERE c.castmethod = 'b' AND
423     NOT EXISTS (SELECT 1 FROM pg_cast k
424                 WHERE k.castmethod = 'b' AND
425                     k.castsource = c.casttarget AND
426                     k.casttarget = c.castsource);
427     castsource     |    casttarget     | castfunc | castcontext 
428 -------------------+-------------------+----------+-------------
429  text              | character         |        0 | i
430  character varying | character         |        0 | i
431  pg_node_tree      | text              |        0 | i
432  cidr              | inet              |        0 | i
433  xml               | text              |        0 | a
434  xml               | character varying |        0 | a
435  xml               | character         |        0 | a
436 (7 rows)
437
438 -- **************** pg_operator ****************
439 -- Look for illegal values in pg_operator fields.
440 SELECT p1.oid, p1.oprname
441 FROM pg_operator as p1
442 WHERE (p1.oprkind != 'b' AND p1.oprkind != 'l' AND p1.oprkind != 'r') OR
443     p1.oprresult = 0 OR p1.oprcode = 0;
444  oid | oprname 
445 -----+---------
446 (0 rows)
447
448 -- Look for missing or unwanted operand types
449 SELECT p1.oid, p1.oprname
450 FROM pg_operator as p1
451 WHERE (p1.oprleft = 0 and p1.oprkind != 'l') OR
452     (p1.oprleft != 0 and p1.oprkind = 'l') OR
453     (p1.oprright = 0 and p1.oprkind != 'r') OR
454     (p1.oprright != 0 and p1.oprkind = 'r');
455  oid | oprname 
456 -----+---------
457 (0 rows)
458
459 -- Look for conflicting operator definitions (same names and input datatypes).
460 SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
461 FROM pg_operator AS p1, pg_operator AS p2
462 WHERE p1.oid != p2.oid AND
463     p1.oprname = p2.oprname AND
464     p1.oprkind = p2.oprkind AND
465     p1.oprleft = p2.oprleft AND
466     p1.oprright = p2.oprright;
467  oid | oprcode | oid | oprcode 
468 -----+---------+-----+---------
469 (0 rows)
470
471 -- Look for commutative operators that don't commute.
472 -- DEFINITIONAL NOTE: If A.oprcom = B, then x A y has the same result as y B x.
473 -- We expect that B will always say that B.oprcom = A as well; that's not
474 -- inherently essential, but it would be inefficient not to mark it so.
475 SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
476 FROM pg_operator AS p1, pg_operator AS p2
477 WHERE p1.oprcom = p2.oid AND
478     (p1.oprkind != 'b' OR
479      p1.oprleft != p2.oprright OR
480      p1.oprright != p2.oprleft OR
481      p1.oprresult != p2.oprresult OR
482      p1.oid != p2.oprcom);
483  oid | oprcode | oid | oprcode 
484 -----+---------+-----+---------
485 (0 rows)
486
487 -- Look for negatory operators that don't agree.
488 -- DEFINITIONAL NOTE: If A.oprnegate = B, then both A and B must yield
489 -- boolean results, and (x A y) == ! (x B y), or the equivalent for
490 -- single-operand operators.
491 -- We expect that B will always say that B.oprnegate = A as well; that's not
492 -- inherently essential, but it would be inefficient not to mark it so.
493 -- Also, A and B had better not be the same operator.
494 SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
495 FROM pg_operator AS p1, pg_operator AS p2
496 WHERE p1.oprnegate = p2.oid AND
497     (p1.oprkind != p2.oprkind OR
498      p1.oprleft != p2.oprleft OR
499      p1.oprright != p2.oprright OR
500      p1.oprresult != 'bool'::regtype OR
501      p2.oprresult != 'bool'::regtype OR
502      p1.oid != p2.oprnegate OR
503      p1.oid = p2.oid);
504  oid | oprcode | oid | oprcode 
505 -----+---------+-----+---------
506 (0 rows)
507
508 -- A mergejoinable or hashjoinable operator must be binary, must return
509 -- boolean, and must have a commutator (itself, unless it's a cross-type
510 -- operator).
511 SELECT p1.oid, p1.oprname FROM pg_operator AS p1
512 WHERE (p1.oprcanmerge OR p1.oprcanhash) AND NOT
513     (p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND p1.oprcom != 0);
514  oid | oprname 
515 -----+---------
516 (0 rows)
517
518 -- What's more, the commutator had better be mergejoinable/hashjoinable too.
519 SELECT p1.oid, p1.oprname, p2.oid, p2.oprname
520 FROM pg_operator AS p1, pg_operator AS p2
521 WHERE p1.oprcom = p2.oid AND
522     (p1.oprcanmerge != p2.oprcanmerge OR
523      p1.oprcanhash != p2.oprcanhash);
524  oid | oprname | oid | oprname 
525 -----+---------+-----+---------
526 (0 rows)
527
528 -- Mergejoinable operators should appear as equality members of btree index
529 -- opfamilies.
530 SELECT p1.oid, p1.oprname
531 FROM pg_operator AS p1
532 WHERE p1.oprcanmerge AND NOT EXISTS
533   (SELECT 1 FROM pg_amop
534    WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND
535          amopopr = p1.oid AND amopstrategy = 3);
536  oid | oprname 
537 -----+---------
538 (0 rows)
539
540 -- And the converse.
541 SELECT p1.oid, p1.oprname, p.amopfamily
542 FROM pg_operator AS p1, pg_amop p
543 WHERE amopopr = p1.oid
544   AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree')
545   AND amopstrategy = 3
546   AND NOT p1.oprcanmerge;
547  oid | oprname | amopfamily 
548 -----+---------+------------
549 (0 rows)
550
551 -- Hashable operators should appear as members of hash index opfamilies.
552 SELECT p1.oid, p1.oprname
553 FROM pg_operator AS p1
554 WHERE p1.oprcanhash AND NOT EXISTS
555   (SELECT 1 FROM pg_amop
556    WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND
557          amopopr = p1.oid AND amopstrategy = 1);
558  oid | oprname 
559 -----+---------
560 (0 rows)
561
562 -- And the converse.
563 SELECT p1.oid, p1.oprname, p.amopfamily
564 FROM pg_operator AS p1, pg_amop p
565 WHERE amopopr = p1.oid
566   AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash')
567   AND NOT p1.oprcanhash;
568  oid | oprname | amopfamily 
569 -----+---------+------------
570 (0 rows)
571
572 -- Check that each operator defined in pg_operator matches its oprcode entry
573 -- in pg_proc.  Easiest to do this separately for each oprkind.
574 SELECT p1.oid, p1.oprname, p2.oid, p2.proname
575 FROM pg_operator AS p1, pg_proc AS p2
576 WHERE p1.oprcode = p2.oid AND
577     p1.oprkind = 'b' AND
578     (p2.pronargs != 2
579      OR NOT binary_coercible(p2.prorettype, p1.oprresult)
580      OR NOT binary_coercible(p1.oprleft, p2.proargtypes[0])
581      OR NOT binary_coercible(p1.oprright, p2.proargtypes[1]));
582  oid | oprname | oid | proname 
583 -----+---------+-----+---------
584 (0 rows)
585
586 SELECT p1.oid, p1.oprname, p2.oid, p2.proname
587 FROM pg_operator AS p1, pg_proc AS p2
588 WHERE p1.oprcode = p2.oid AND
589     p1.oprkind = 'l' AND
590     (p2.pronargs != 1
591      OR NOT binary_coercible(p2.prorettype, p1.oprresult)
592      OR NOT binary_coercible(p1.oprright, p2.proargtypes[0])
593      OR p1.oprleft != 0);
594  oid | oprname | oid | proname 
595 -----+---------+-----+---------
596 (0 rows)
597
598 SELECT p1.oid, p1.oprname, p2.oid, p2.proname
599 FROM pg_operator AS p1, pg_proc AS p2
600 WHERE p1.oprcode = p2.oid AND
601     p1.oprkind = 'r' AND
602     (p2.pronargs != 1
603      OR NOT binary_coercible(p2.prorettype, p1.oprresult)
604      OR NOT binary_coercible(p1.oprleft, p2.proargtypes[0])
605      OR p1.oprright != 0);
606  oid | oprname | oid | proname 
607 -----+---------+-----+---------
608 (0 rows)
609
610 -- If the operator is mergejoinable or hashjoinable, its underlying function
611 -- should not be volatile.
612 SELECT p1.oid, p1.oprname, p2.oid, p2.proname
613 FROM pg_operator AS p1, pg_proc AS p2
614 WHERE p1.oprcode = p2.oid AND
615     (p1.oprcanmerge OR p1.oprcanhash) AND
616     p2.provolatile = 'v';
617  oid | oprname | oid | proname 
618 -----+---------+-----+---------
619 (0 rows)
620
621 -- If oprrest is set, the operator must return boolean,
622 -- and it must link to a proc with the right signature
623 -- to be a restriction selectivity estimator.
624 -- The proc signature we want is: float8 proc(internal, oid, internal, int4)
625 SELECT p1.oid, p1.oprname, p2.oid, p2.proname
626 FROM pg_operator AS p1, pg_proc AS p2
627 WHERE p1.oprrest = p2.oid AND
628     (p1.oprresult != 'bool'::regtype OR
629      p2.prorettype != 'float8'::regtype OR p2.proretset OR
630      p2.pronargs != 4 OR
631      p2.proargtypes[0] != 'internal'::regtype OR
632      p2.proargtypes[1] != 'oid'::regtype OR
633      p2.proargtypes[2] != 'internal'::regtype OR
634      p2.proargtypes[3] != 'int4'::regtype);
635  oid | oprname | oid | proname 
636 -----+---------+-----+---------
637 (0 rows)
638
639 -- If oprjoin is set, the operator must be a binary boolean op,
640 -- and it must link to a proc with the right signature
641 -- to be a join selectivity estimator.
642 -- The proc signature we want is: float8 proc(internal, oid, internal, int2, internal)
643 -- (Note: the old signature with only 4 args is still allowed, but no core
644 -- estimator should be using it.)
645 SELECT p1.oid, p1.oprname, p2.oid, p2.proname
646 FROM pg_operator AS p1, pg_proc AS p2
647 WHERE p1.oprjoin = p2.oid AND
648     (p1.oprkind != 'b' OR p1.oprresult != 'bool'::regtype OR
649      p2.prorettype != 'float8'::regtype OR p2.proretset OR
650      p2.pronargs != 5 OR
651      p2.proargtypes[0] != 'internal'::regtype OR
652      p2.proargtypes[1] != 'oid'::regtype OR
653      p2.proargtypes[2] != 'internal'::regtype OR
654      p2.proargtypes[3] != 'int2'::regtype OR
655      p2.proargtypes[4] != 'internal'::regtype);
656  oid | oprname | oid | proname 
657 -----+---------+-----+---------
658 (0 rows)
659
660 -- Insist that all built-in pg_operator entries have descriptions
661 SELECT p1.oid, p1.oprname
662 FROM pg_operator as p1 LEFT JOIN pg_description as d
663      ON p1.tableoid = d.classoid and p1.oid = d.objoid and d.objsubid = 0
664 WHERE d.classoid IS NULL AND p1.oid <= 9999;
665  oid | oprname 
666 -----+---------
667 (0 rows)
668
669 -- Check that operators' underlying functions have suitable comments,
670 -- namely 'implementation of XXX operator'.  In some cases involving legacy
671 -- names for operators, there are multiple operators referencing the same
672 -- pg_proc entry, so ignore operators whose comments say they are deprecated.
673 -- We also have a few functions that are both operator support and meant to
674 -- be called directly; those should have comments matching their operator.
675 WITH funcdescs AS (
676   SELECT p.oid as p_oid, proname, o.oid as o_oid,
677     obj_description(p.oid, 'pg_proc') as prodesc,
678     'implementation of ' || oprname || ' operator' as expecteddesc,
679     obj_description(o.oid, 'pg_operator') as oprdesc
680   FROM pg_proc p JOIN pg_operator o ON oprcode = p.oid
681   WHERE o.oid <= 9999
682 )
683 SELECT * FROM funcdescs
684   WHERE prodesc IS DISTINCT FROM expecteddesc
685     AND oprdesc NOT LIKE 'deprecated%'
686     AND prodesc IS DISTINCT FROM oprdesc;
687  p_oid | proname | o_oid | prodesc | expecteddesc | oprdesc 
688 -------+---------+-------+---------+--------------+---------
689 (0 rows)
690
691 -- **************** pg_aggregate ****************
692 -- Look for illegal values in pg_aggregate fields.
693 SELECT ctid, aggfnoid::oid
694 FROM pg_aggregate as p1
695 WHERE aggfnoid = 0 OR aggtransfn = 0 OR aggtranstype = 0;
696  ctid | aggfnoid 
697 ------+----------
698 (0 rows)
699
700 -- Make sure the matching pg_proc entry is sensible, too.
701 SELECT a.aggfnoid::oid, p.proname
702 FROM pg_aggregate as a, pg_proc as p
703 WHERE a.aggfnoid = p.oid AND
704     (NOT p.proisagg OR p.proretset);
705  aggfnoid | proname 
706 ----------+---------
707 (0 rows)
708
709 -- Make sure there are no proisagg pg_proc entries without matches.
710 SELECT oid, proname
711 FROM pg_proc as p
712 WHERE p.proisagg AND
713     NOT EXISTS (SELECT 1 FROM pg_aggregate a WHERE a.aggfnoid = p.oid);
714  oid | proname 
715 -----+---------
716 (0 rows)
717
718 -- If there is no finalfn then the output type must be the transtype.
719 SELECT a.aggfnoid::oid, p.proname
720 FROM pg_aggregate as a, pg_proc as p
721 WHERE a.aggfnoid = p.oid AND
722     a.aggfinalfn = 0 AND p.prorettype != a.aggtranstype;
723  aggfnoid | proname 
724 ----------+---------
725 (0 rows)
726
727 -- Cross-check transfn against its entry in pg_proc.
728 -- NOTE: use physically_coercible here, not binary_coercible, because
729 -- max and min on abstime are implemented using int4larger/int4smaller.
730 SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname
731 FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr
732 WHERE a.aggfnoid = p.oid AND
733     a.aggtransfn = ptr.oid AND
734     (ptr.proretset
735      OR NOT (ptr.pronargs = p.pronargs + 1)
736      OR NOT physically_coercible(ptr.prorettype, a.aggtranstype)
737      OR NOT physically_coercible(a.aggtranstype, ptr.proargtypes[0])
738      OR (p.pronargs > 0 AND
739          NOT physically_coercible(p.proargtypes[0], ptr.proargtypes[1]))
740      OR (p.pronargs > 1 AND
741          NOT physically_coercible(p.proargtypes[1], ptr.proargtypes[2]))
742      OR (p.pronargs > 2 AND
743          NOT physically_coercible(p.proargtypes[2], ptr.proargtypes[3]))
744      -- we could carry the check further, but that's enough for now
745     );
746  aggfnoid | proname | oid | proname 
747 ----------+---------+-----+---------
748 (0 rows)
749
750 -- Cross-check finalfn (if present) against its entry in pg_proc.
751 SELECT a.aggfnoid::oid, p.proname, pfn.oid, pfn.proname
752 FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS pfn
753 WHERE a.aggfnoid = p.oid AND
754     a.aggfinalfn = pfn.oid AND
755     (pfn.proretset
756      OR NOT binary_coercible(pfn.prorettype, p.prorettype)
757      OR pfn.pronargs != 1
758      OR NOT binary_coercible(a.aggtranstype, pfn.proargtypes[0]));
759  aggfnoid | proname | oid | proname 
760 ----------+---------+-----+---------
761 (0 rows)
762
763 -- If transfn is strict then either initval should be non-NULL, or
764 -- input type should match transtype so that the first non-null input
765 -- can be assigned as the state value.
766 SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname
767 FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr
768 WHERE a.aggfnoid = p.oid AND
769     a.aggtransfn = ptr.oid AND ptr.proisstrict AND
770     a.agginitval IS NULL AND
771     NOT binary_coercible(p.proargtypes[0], a.aggtranstype);
772  aggfnoid | proname | oid | proname 
773 ----------+---------+-----+---------
774 (0 rows)
775
776 -- Cross-check aggsortop (if present) against pg_operator.
777 -- We expect to find only "<" for "min" and ">" for "max".
778 SELECT DISTINCT proname, oprname
779 FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p
780 WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid
781 ORDER BY 1;
782  proname | oprname 
783 ---------+---------
784  max     | >
785  min     | <
786 (2 rows)
787
788 -- Check datatypes match
789 SELECT a.aggfnoid::oid, o.oid
790 FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p
791 WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND
792     (oprkind != 'b' OR oprresult != 'boolean'::regtype
793      OR oprleft != p.proargtypes[0] OR oprright != p.proargtypes[0]);
794  aggfnoid | oid 
795 ----------+-----
796 (0 rows)
797
798 -- Check operator is a suitable btree opfamily member
799 SELECT a.aggfnoid::oid, o.oid
800 FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p
801 WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND
802     NOT EXISTS(SELECT 1 FROM pg_amop
803                WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree')
804                      AND amopopr = o.oid
805                      AND amoplefttype = o.oprleft
806                      AND amoprighttype = o.oprright);
807  aggfnoid | oid 
808 ----------+-----
809 (0 rows)
810
811 -- Check correspondence of btree strategies and names
812 SELECT DISTINCT proname, oprname, amopstrategy
813 FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p,
814      pg_amop as ao
815 WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND
816     amopopr = o.oid AND
817     amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree')
818 ORDER BY 1, 2;
819  proname | oprname | amopstrategy 
820 ---------+---------+--------------
821  max     | >       |            5
822  min     | <       |            1
823 (2 rows)
824
825 -- Check that there are not aggregates with the same name and different
826 -- numbers of arguments.  While not technically wrong, we have a project policy
827 -- to avoid this because it opens the door for confusion in connection with
828 -- ORDER BY: novices frequently put the ORDER BY in the wrong place.
829 -- See the fate of the single-argument form of string_agg() for history.
830 -- The only aggregates that should show up here are count(x) and count(*).
831 SELECT p1.oid::regprocedure, p2.oid::regprocedure
832 FROM pg_proc AS p1, pg_proc AS p2
833 WHERE p1.oid < p2.oid AND p1.proname = p2.proname AND
834     p1.proisagg AND p2.proisagg AND
835     array_dims(p1.proargtypes) != array_dims(p2.proargtypes)
836 ORDER BY 1;
837      oid      |   oid   
838 --------------+---------
839  count("any") | count()
840 (1 row)
841
842 -- For the same reason, aggregates with default arguments are no good.
843 SELECT oid, proname
844 FROM pg_proc AS p
845 WHERE proisagg AND proargdefaults IS NOT NULL;
846  oid | proname 
847 -----+---------
848 (0 rows)
849
850 -- **************** pg_opfamily ****************
851 -- Look for illegal values in pg_opfamily fields
852 SELECT p1.oid
853 FROM pg_opfamily as p1
854 WHERE p1.opfmethod = 0 OR p1.opfnamespace = 0;
855  oid 
856 -----
857 (0 rows)
858
859 -- **************** pg_opclass ****************
860 -- Look for illegal values in pg_opclass fields
861 SELECT p1.oid
862 FROM pg_opclass AS p1
863 WHERE p1.opcmethod = 0 OR p1.opcnamespace = 0 OR p1.opcfamily = 0
864     OR p1.opcintype = 0;
865  oid 
866 -----
867 (0 rows)
868
869 -- opcmethod must match owning opfamily's opfmethod
870 SELECT p1.oid, p2.oid
871 FROM pg_opclass AS p1, pg_opfamily AS p2
872 WHERE p1.opcfamily = p2.oid AND p1.opcmethod != p2.opfmethod;
873  oid | oid 
874 -----+-----
875 (0 rows)
876
877 -- There should not be multiple entries in pg_opclass with opcdefault true
878 -- and the same opcmethod/opcintype combination.
879 SELECT p1.oid, p2.oid
880 FROM pg_opclass AS p1, pg_opclass AS p2
881 WHERE p1.oid != p2.oid AND
882     p1.opcmethod = p2.opcmethod AND p1.opcintype = p2.opcintype AND
883     p1.opcdefault AND p2.opcdefault;
884  oid | oid 
885 -----+-----
886 (0 rows)
887
888 -- **************** pg_amop ****************
889 -- Look for illegal values in pg_amop fields
890 SELECT p1.amopfamily, p1.amopstrategy
891 FROM pg_amop as p1
892 WHERE p1.amopfamily = 0 OR p1.amoplefttype = 0 OR p1.amoprighttype = 0
893     OR p1.amopopr = 0 OR p1.amopmethod = 0 OR p1.amopstrategy < 1;
894  amopfamily | amopstrategy 
895 ------------+--------------
896 (0 rows)
897
898 SELECT p1.amopfamily, p1.amopstrategy
899 FROM pg_amop as p1
900 WHERE NOT ((p1.amoppurpose = 's' AND p1.amopsortfamily = 0) OR
901            (p1.amoppurpose = 'o' AND p1.amopsortfamily <> 0));
902  amopfamily | amopstrategy 
903 ------------+--------------
904 (0 rows)
905
906 -- amoplefttype/amoprighttype must match the operator
907 SELECT p1.oid, p2.oid
908 FROM pg_amop AS p1, pg_operator AS p2
909 WHERE p1.amopopr = p2.oid AND NOT
910     (p1.amoplefttype = p2.oprleft AND p1.amoprighttype = p2.oprright);
911  oid | oid 
912 -----+-----
913 (0 rows)
914
915 -- amopmethod must match owning opfamily's opfmethod
916 SELECT p1.oid, p2.oid
917 FROM pg_amop AS p1, pg_opfamily AS p2
918 WHERE p1.amopfamily = p2.oid AND p1.amopmethod != p2.opfmethod;
919  oid | oid 
920 -----+-----
921 (0 rows)
922
923 -- amopsortfamily, if present, must reference a btree family
924 SELECT p1.amopfamily, p1.amopstrategy
925 FROM pg_amop AS p1
926 WHERE p1.amopsortfamily <> 0 AND NOT EXISTS
927     (SELECT 1 from pg_opfamily op WHERE op.oid = p1.amopsortfamily
928      AND op.opfmethod = (SELECT oid FROM pg_am WHERE amname = 'btree'));
929  amopfamily | amopstrategy 
930 ------------+--------------
931 (0 rows)
932
933 -- check for ordering operators not supported by parent AM
934 SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.amname
935 FROM pg_amop AS p1, pg_am AS p2
936 WHERE p1.amopmethod = p2.oid AND
937     p1.amoppurpose = 'o' AND NOT p2.amcanorderbyop;
938  amopfamily | amopopr | oid | amname 
939 ------------+---------+-----+--------
940 (0 rows)
941
942 -- Cross-check amopstrategy index against parent AM
943 SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.amname
944 FROM pg_amop AS p1, pg_am AS p2
945 WHERE p1.amopmethod = p2.oid AND
946     p1.amopstrategy > p2.amstrategies AND p2.amstrategies <> 0;
947  amopfamily | amopopr | oid | amname 
948 ------------+---------+-----+--------
949 (0 rows)
950
951 -- Detect missing pg_amop entries: should have as many strategy operators
952 -- as AM expects for each datatype combination supported by the opfamily.
953 -- We can't check this for AMs with variable strategy sets.
954 SELECT p1.amname, p2.amoplefttype, p2.amoprighttype
955 FROM pg_am AS p1, pg_amop AS p2
956 WHERE p2.amopmethod = p1.oid AND
957     p1.amstrategies <> 0 AND
958     p1.amstrategies != (SELECT count(*) FROM pg_amop AS p3
959                         WHERE p3.amopfamily = p2.amopfamily AND
960                               p3.amoplefttype = p2.amoplefttype AND
961                               p3.amoprighttype = p2.amoprighttype AND
962                               p3.amoppurpose = 's');
963  amname | amoplefttype | amoprighttype 
964 --------+--------------+---------------
965 (0 rows)
966
967 -- Currently, none of the AMs with fixed strategy sets support ordering ops.
968 SELECT p1.amname, p2.amopfamily, p2.amopstrategy
969 FROM pg_am AS p1, pg_amop AS p2
970 WHERE p2.amopmethod = p1.oid AND
971     p1.amstrategies <> 0 AND p2.amoppurpose <> 's';
972  amname | amopfamily | amopstrategy 
973 --------+------------+--------------
974 (0 rows)
975
976 -- Check that amopopr points at a reasonable-looking operator, ie a binary
977 -- operator.  If it's a search operator it had better yield boolean,
978 -- otherwise an input type of its sort opfamily.
979 SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname
980 FROM pg_amop AS p1, pg_operator AS p2
981 WHERE p1.amopopr = p2.oid AND
982     p2.oprkind != 'b';
983  amopfamily | amopopr | oid | oprname 
984 ------------+---------+-----+---------
985 (0 rows)
986
987 SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname
988 FROM pg_amop AS p1, pg_operator AS p2
989 WHERE p1.amopopr = p2.oid AND p1.amoppurpose = 's' AND
990     p2.oprresult != 'bool'::regtype;
991  amopfamily | amopopr | oid | oprname 
992 ------------+---------+-----+---------
993 (0 rows)
994
995 SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname
996 FROM pg_amop AS p1, pg_operator AS p2
997 WHERE p1.amopopr = p2.oid AND p1.amoppurpose = 'o' AND NOT EXISTS
998     (SELECT 1 FROM pg_opclass op
999      WHERE opcfamily = p1.amopsortfamily AND opcintype = p2.oprresult);
1000  amopfamily | amopopr | oid | oprname 
1001 ------------+---------+-----+---------
1002 (0 rows)
1003
1004 -- Make a list of all the distinct operator names being used in particular
1005 -- strategy slots.  This is a bit hokey, since the list might need to change
1006 -- in future releases, but it's an effective way of spotting mistakes such as
1007 -- swapping two operators within a family.
1008 SELECT DISTINCT amopmethod, amopstrategy, oprname
1009 FROM pg_amop p1 LEFT JOIN pg_operator p2 ON amopopr = p2.oid
1010 ORDER BY 1, 2, 3;
1011  amopmethod | amopstrategy | oprname 
1012 ------------+--------------+---------
1013         403 |            1 | <
1014         403 |            1 | ~<~
1015         403 |            2 | <=
1016         403 |            2 | ~<=~
1017         403 |            3 | =
1018         403 |            4 | >=
1019         403 |            4 | ~>=~
1020         403 |            5 | >
1021         403 |            5 | ~>~
1022         405 |            1 | =
1023         783 |            1 | <<
1024         783 |            1 | @@
1025         783 |            2 | &<
1026         783 |            3 | &&
1027         783 |            4 | &>
1028         783 |            5 | >>
1029         783 |            6 | -|-
1030         783 |            6 | ~=
1031         783 |            7 | @>
1032         783 |            8 | <@
1033         783 |            9 | &<|
1034         783 |           10 | <<|
1035         783 |           10 | <^
1036         783 |           11 | >^
1037         783 |           11 | |>>
1038         783 |           12 | |&>
1039         783 |           13 | ~
1040         783 |           14 | @
1041         783 |           15 | <->
1042         783 |           16 | @>
1043         783 |           18 | =
1044         783 |           27 | @>
1045         783 |           28 | <@
1046         783 |           47 | @>
1047         783 |           48 | <@
1048         783 |           67 | @>
1049         783 |           68 | <@
1050        2742 |            1 | &&
1051        2742 |            1 | @@
1052        2742 |            2 | @>
1053        2742 |            2 | @@@
1054        2742 |            3 | <@
1055        2742 |            4 | =
1056 (43 rows)
1057
1058 -- Check that all opclass search operators have selectivity estimators.
1059 -- This is not absolutely required, but it seems a reasonable thing
1060 -- to insist on for all standard datatypes.
1061 SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname
1062 FROM pg_amop AS p1, pg_operator AS p2
1063 WHERE p1.amopopr = p2.oid AND p1.amoppurpose = 's' AND
1064     (p2.oprrest = 0 OR p2.oprjoin = 0);
1065  amopfamily | amopopr | oid | oprname 
1066 ------------+---------+-----+---------
1067 (0 rows)
1068
1069 -- Check that each opclass in an opfamily has associated operators, that is
1070 -- ones whose oprleft matches opcintype (possibly by coercion).
1071 SELECT p1.opcname, p1.opcfamily
1072 FROM pg_opclass AS p1
1073 WHERE NOT EXISTS(SELECT 1 FROM pg_amop AS p2
1074                  WHERE p2.amopfamily = p1.opcfamily
1075                    AND binary_coercible(p1.opcintype, p2.amoplefttype));
1076  opcname | opcfamily 
1077 ---------+-----------
1078 (0 rows)
1079
1080 -- Operators that are primary members of opclasses must be immutable (else
1081 -- it suggests that the index ordering isn't fixed).  Operators that are
1082 -- cross-type members need only be stable, since they are just shorthands
1083 -- for index probe queries.
1084 SELECT p1.amopfamily, p1.amopopr, p2.oprname, p3.prosrc
1085 FROM pg_amop AS p1, pg_operator AS p2, pg_proc AS p3
1086 WHERE p1.amopopr = p2.oid AND p2.oprcode = p3.oid AND
1087     p1.amoplefttype = p1.amoprighttype AND
1088     p3.provolatile != 'i';
1089  amopfamily | amopopr | oprname | prosrc 
1090 ------------+---------+---------+--------
1091 (0 rows)
1092
1093 SELECT p1.amopfamily, p1.amopopr, p2.oprname, p3.prosrc
1094 FROM pg_amop AS p1, pg_operator AS p2, pg_proc AS p3
1095 WHERE p1.amopopr = p2.oid AND p2.oprcode = p3.oid AND
1096     p1.amoplefttype != p1.amoprighttype AND
1097     p3.provolatile = 'v';
1098  amopfamily | amopopr | oprname | prosrc 
1099 ------------+---------+---------+--------
1100 (0 rows)
1101
1102 -- Multiple-datatype btree opfamilies should provide closed sets of equality
1103 -- operators; that is if you provide int2 = int4 and int4 = int8 then you
1104 -- should also provide int2 = int8 (and commutators of all these).  This is
1105 -- important because the planner tries to deduce additional qual clauses from
1106 -- transitivity of mergejoinable operators.  If there are clauses
1107 -- int2var = int4var and int4var = int8var, the planner will want to deduce
1108 -- int2var = int8var ... so there should be a way to represent that.  While
1109 -- a missing cross-type operator is now only an efficiency loss rather than
1110 -- an error condition, it still seems reasonable to insist that all built-in
1111 -- opfamilies be complete.
1112 -- check commutative closure
1113 SELECT p1.amoplefttype, p1.amoprighttype
1114 FROM pg_amop AS p1
1115 WHERE p1.amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND
1116     p1.amopstrategy = 3 AND
1117     p1.amoplefttype != p1.amoprighttype AND
1118     NOT EXISTS(SELECT 1 FROM pg_amop p2 WHERE
1119                  p2.amopfamily = p1.amopfamily AND
1120                  p2.amoplefttype = p1.amoprighttype AND
1121                  p2.amoprighttype = p1.amoplefttype AND
1122                  p2.amopstrategy = 3);
1123  amoplefttype | amoprighttype 
1124 --------------+---------------
1125 (0 rows)
1126
1127 -- check transitive closure
1128 SELECT p1.amoplefttype, p1.amoprighttype, p2.amoprighttype
1129 FROM pg_amop AS p1, pg_amop AS p2
1130 WHERE p1.amopfamily = p2.amopfamily AND
1131     p1.amoprighttype = p2.amoplefttype AND
1132     p1.amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND
1133     p2.amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND
1134     p1.amopstrategy = 3 AND p2.amopstrategy = 3 AND
1135     p1.amoplefttype != p1.amoprighttype AND
1136     p2.amoplefttype != p2.amoprighttype AND
1137     NOT EXISTS(SELECT 1 FROM pg_amop p3 WHERE
1138                  p3.amopfamily = p1.amopfamily AND
1139                  p3.amoplefttype = p1.amoplefttype AND
1140                  p3.amoprighttype = p2.amoprighttype AND
1141                  p3.amopstrategy = 3);
1142  amoplefttype | amoprighttype | amoprighttype 
1143 --------------+---------------+---------------
1144 (0 rows)
1145
1146 -- We also expect that built-in multiple-datatype hash opfamilies provide
1147 -- complete sets of cross-type operators.  Again, this isn't required, but
1148 -- it is reasonable to expect it for built-in opfamilies.
1149 -- if same family has x=x and y=y, it should have x=y
1150 SELECT p1.amoplefttype, p2.amoplefttype
1151 FROM pg_amop AS p1, pg_amop AS p2
1152 WHERE p1.amopfamily = p2.amopfamily AND
1153     p1.amoplefttype = p1.amoprighttype AND
1154     p2.amoplefttype = p2.amoprighttype AND
1155     p1.amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND
1156     p2.amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND
1157     p1.amopstrategy = 1 AND p2.amopstrategy = 1 AND
1158     p1.amoplefttype != p2.amoplefttype AND
1159     NOT EXISTS(SELECT 1 FROM pg_amop p3 WHERE
1160                  p3.amopfamily = p1.amopfamily AND
1161                  p3.amoplefttype = p1.amoplefttype AND
1162                  p3.amoprighttype = p2.amoplefttype AND
1163                  p3.amopstrategy = 1);
1164  amoplefttype | amoplefttype 
1165 --------------+--------------
1166 (0 rows)
1167
1168 -- **************** pg_amproc ****************
1169 -- Look for illegal values in pg_amproc fields
1170 SELECT p1.amprocfamily, p1.amprocnum
1171 FROM pg_amproc as p1
1172 WHERE p1.amprocfamily = 0 OR p1.amproclefttype = 0 OR p1.amprocrighttype = 0
1173     OR p1.amprocnum < 1 OR p1.amproc = 0;
1174  amprocfamily | amprocnum 
1175 --------------+-----------
1176 (0 rows)
1177
1178 -- Cross-check amprocnum index against parent AM
1179 SELECT p1.amprocfamily, p1.amprocnum, p2.oid, p2.amname
1180 FROM pg_amproc AS p1, pg_am AS p2, pg_opfamily AS p3
1181 WHERE p1.amprocfamily = p3.oid AND p3.opfmethod = p2.oid AND
1182     p1.amprocnum > p2.amsupport;
1183  amprocfamily | amprocnum | oid | amname 
1184 --------------+-----------+-----+--------
1185 (0 rows)
1186
1187 -- Detect missing pg_amproc entries: should have as many support functions
1188 -- as AM expects for each datatype combination supported by the opfamily.
1189 -- btree/GiST/GIN each allow one optional support function, though.
1190 SELECT p1.amname, p2.opfname, p3.amproclefttype, p3.amprocrighttype
1191 FROM pg_am AS p1, pg_opfamily AS p2, pg_amproc AS p3
1192 WHERE p2.opfmethod = p1.oid AND p3.amprocfamily = p2.oid AND
1193     (SELECT count(*) FROM pg_amproc AS p4
1194      WHERE p4.amprocfamily = p2.oid AND
1195            p4.amproclefttype = p3.amproclefttype AND
1196            p4.amprocrighttype = p3.amprocrighttype)
1197     NOT BETWEEN
1198       (CASE WHEN p1.amname IN ('btree', 'gist', 'gin') THEN p1.amsupport - 1
1199             ELSE p1.amsupport END)
1200       AND p1.amsupport;
1201  amname | opfname | amproclefttype | amprocrighttype 
1202 --------+---------+----------------+-----------------
1203 (0 rows)
1204
1205 -- Also, check if there are any pg_opclass entries that don't seem to have
1206 -- pg_amproc support.  Again, opclasses with an optional support proc have
1207 -- to be checked specially.
1208 SELECT amname, opcname, count(*)
1209 FROM pg_am am JOIN pg_opclass op ON opcmethod = am.oid
1210      LEFT JOIN pg_amproc p ON amprocfamily = opcfamily AND
1211          amproclefttype = amprocrighttype AND amproclefttype = opcintype
1212 WHERE am.amname <> 'btree' AND am.amname <> 'gist' AND am.amname <> 'gin'
1213 GROUP BY amname, amsupport, opcname, amprocfamily
1214 HAVING count(*) != amsupport OR amprocfamily IS NULL;
1215  amname | opcname | count 
1216 --------+---------+-------
1217 (0 rows)
1218
1219 SELECT amname, opcname, count(*)
1220 FROM pg_am am JOIN pg_opclass op ON opcmethod = am.oid
1221      LEFT JOIN pg_amproc p ON amprocfamily = opcfamily AND
1222          amproclefttype = amprocrighttype AND amproclefttype = opcintype
1223 WHERE am.amname = 'btree' OR am.amname = 'gist' OR am.amname = 'gin'
1224 GROUP BY amname, amsupport, opcname, amprocfamily
1225 HAVING (count(*) != amsupport AND count(*) != amsupport - 1)
1226     OR amprocfamily IS NULL;
1227  amname | opcname | count 
1228 --------+---------+-------
1229 (0 rows)
1230
1231 -- Unfortunately, we can't check the amproc link very well because the
1232 -- signature of the function may be different for different support routines
1233 -- or different base data types.
1234 -- We can check that all the referenced instances of the same support
1235 -- routine number take the same number of parameters, but that's about it
1236 -- for a general check...
1237 SELECT p1.amprocfamily, p1.amprocnum,
1238         p2.oid, p2.proname,
1239         p3.opfname,
1240         p4.amprocfamily, p4.amprocnum,
1241         p5.oid, p5.proname,
1242         p6.opfname
1243 FROM pg_amproc AS p1, pg_proc AS p2, pg_opfamily AS p3,
1244      pg_amproc AS p4, pg_proc AS p5, pg_opfamily AS p6
1245 WHERE p1.amprocfamily = p3.oid AND p4.amprocfamily = p6.oid AND
1246     p3.opfmethod = p6.opfmethod AND p1.amprocnum = p4.amprocnum AND
1247     p1.amproc = p2.oid AND p4.amproc = p5.oid AND
1248     (p2.proretset OR p5.proretset OR p2.pronargs != p5.pronargs);
1249  amprocfamily | amprocnum | oid | proname | opfname | amprocfamily | amprocnum | oid | proname | opfname 
1250 --------------+-----------+-----+---------+---------+--------------+-----------+-----+---------+---------
1251 (0 rows)
1252
1253 -- For btree, though, we can do better since we know the support routines
1254 -- must be of the form cmp(lefttype, righttype) returns int4
1255 -- or sortsupport(internal) returns void.
1256 SELECT p1.amprocfamily, p1.amprocnum,
1257         p2.oid, p2.proname,
1258         p3.opfname
1259 FROM pg_amproc AS p1, pg_proc AS p2, pg_opfamily AS p3
1260 WHERE p3.opfmethod = (SELECT oid FROM pg_am WHERE amname = 'btree')
1261     AND p1.amprocfamily = p3.oid AND p1.amproc = p2.oid AND
1262     (CASE WHEN amprocnum = 1
1263           THEN prorettype != 'int4'::regtype OR proretset OR pronargs != 2
1264                OR proargtypes[0] != amproclefttype
1265                OR proargtypes[1] != amprocrighttype
1266           WHEN amprocnum = 2
1267           THEN prorettype != 'void'::regtype OR proretset OR pronargs != 1
1268                OR proargtypes[0] != 'internal'::regtype
1269           ELSE true END);
1270  amprocfamily | amprocnum | oid | proname | opfname 
1271 --------------+-----------+-----+---------+---------
1272 (0 rows)
1273
1274 -- For hash we can also do a little better: the support routines must be
1275 -- of the form hash(lefttype) returns int4.  There are several cases where
1276 -- we cheat and use a hash function that is physically compatible with the
1277 -- datatype even though there's no cast, so this check does find a small
1278 -- number of entries.
1279 SELECT p1.amprocfamily, p1.amprocnum, p2.proname, p3.opfname
1280 FROM pg_amproc AS p1, pg_proc AS p2, pg_opfamily AS p3
1281 WHERE p3.opfmethod = (SELECT oid FROM pg_am WHERE amname = 'hash')
1282     AND p1.amprocfamily = p3.oid AND p1.amproc = p2.oid AND
1283     (amprocnum != 1
1284      OR proretset
1285      OR prorettype != 'int4'::regtype
1286      OR pronargs != 1
1287      OR NOT physically_coercible(amproclefttype, proargtypes[0])
1288      OR amproclefttype != amprocrighttype)
1289 ORDER BY 1;
1290  amprocfamily | amprocnum |    proname     |     opfname     
1291 --------------+-----------+----------------+-----------------
1292           435 |         1 | hashint4       | date_ops
1293          1999 |         1 | timestamp_hash | timestamptz_ops
1294          2222 |         1 | hashchar       | bool_ops
1295          2223 |         1 | hashvarlena    | bytea_ops
1296          2225 |         1 | hashint4       | xid_ops
1297          2226 |         1 | hashint4       | cid_ops
1298 (6 rows)
1299
1300 -- Support routines that are primary members of opfamilies must be immutable
1301 -- (else it suggests that the index ordering isn't fixed).  But cross-type
1302 -- members need only be stable, since they are just shorthands
1303 -- for index probe queries.
1304 SELECT p1.amprocfamily, p1.amproc, p2.prosrc
1305 FROM pg_amproc AS p1, pg_proc AS p2
1306 WHERE p1.amproc = p2.oid AND
1307     p1.amproclefttype = p1.amprocrighttype AND
1308     p2.provolatile != 'i';
1309  amprocfamily | amproc | prosrc 
1310 --------------+--------+--------
1311 (0 rows)
1312
1313 SELECT p1.amprocfamily, p1.amproc, p2.prosrc
1314 FROM pg_amproc AS p1, pg_proc AS p2
1315 WHERE p1.amproc = p2.oid AND
1316     p1.amproclefttype != p1.amprocrighttype AND
1317     p2.provolatile = 'v';
1318  amprocfamily | amproc | prosrc 
1319 --------------+--------+--------
1320 (0 rows)
1321