OSDN Git Service

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