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