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