3 -- Sanity checks for common errors in making operator/procedure system tables:
4 -- pg_operator, pg_proc, pg_cast, pg_conversion, pg_aggregate, pg_am,
5 -- pg_amop, pg_amproc, pg_opclass, pg_opfamily, pg_index.
7 -- Every test failure in this file should be closely inspected.
8 -- The description of the failing test should be read carefully before
9 -- adjusting the expected output. In most cases, the queries should
10 -- not find *any* matching entries.
12 -- NB: we assume the oidjoins test will have caught any dangling links,
13 -- that is OID or REGPROC fields that are not zero and do not match some
14 -- row in the linked-to table. However, if we want to enforce that a link
15 -- field can't be 0, we have to check it here.
17 -- NB: run this test earlier than the create_operator test, because
18 -- that test creates some bogus operators...
19 -- **************** pg_proc ****************
20 -- Look for illegal values in pg_proc fields.
21 SELECT p1.oid, p1.proname
23 WHERE p1.prolang = 0 OR p1.prorettype = 0 OR
25 p1.pronargdefaults < 0 OR
26 p1.pronargdefaults > p1.pronargs OR
27 array_lower(p1.proargtypes, 1) != 0 OR
28 array_upper(p1.proargtypes, 1) != p1.pronargs-1 OR
29 0::oid = ANY (p1.proargtypes) OR
31 CASE WHEN proretset THEN prorows <= 0 ELSE prorows != 0 END OR
32 prokind NOT IN ('f', 'a', 'w', 'p') OR
33 provolatile NOT IN ('i', 's', 'v') OR
34 proparallel NOT IN ('s', 'r', 'u');
39 -- prosrc should never be null; it can be empty only if prosqlbody isn't null
40 SELECT p1.oid, p1.proname
47 SELECT p1.oid, p1.proname
49 WHERE (prosrc = '' OR prosrc = '-') AND prosqlbody IS NULL;
54 -- proretset should only be set for normal functions
55 SELECT p1.oid, p1.proname
57 WHERE proretset AND prokind != 'f';
62 -- currently, no built-in functions should be SECURITY DEFINER;
63 -- this might change in future, but there will probably never be many.
64 SELECT p1.oid, p1.proname
72 -- pronargdefaults should be 0 iff proargdefaults is null
73 SELECT p1.oid, p1.proname
75 WHERE (pronargdefaults <> 0) != (proargdefaults IS NOT NULL);
80 -- probin should be non-empty for C functions, null everywhere else
81 SELECT p1.oid, p1.proname
83 WHERE prolang = 13 AND (probin IS NULL OR probin = '' OR probin = '-');
88 SELECT p1.oid, p1.proname
90 WHERE prolang != 13 AND probin IS NOT NULL;
95 -- Look for conflicting proc definitions (same names and input datatypes).
96 -- (This test should be dead code now that we have the unique index
97 -- pg_proc_proname_args_nsp_index, but I'll leave it in anyway.)
98 SELECT p1.oid, p1.proname, p2.oid, p2.proname
99 FROM pg_proc AS p1, pg_proc AS p2
100 WHERE p1.oid != p2.oid AND
101 p1.proname = p2.proname AND
102 p1.pronargs = p2.pronargs AND
103 p1.proargtypes = p2.proargtypes;
104 oid | proname | oid | proname
105 -----+---------+-----+---------
108 -- Considering only built-in procs (prolang = 12), look for multiple uses
109 -- of the same internal function (ie, matching prosrc fields). It's OK to
110 -- have several entries with different pronames for the same internal function,
111 -- but conflicts in the number of arguments and other critical items should
112 -- be complained of. (We don't check data types here; see next query.)
113 -- Note: ignore aggregate functions here, since they all point to the same
114 -- dummy built-in function.
115 SELECT p1.oid, p1.proname, p2.oid, p2.proname
116 FROM pg_proc AS p1, pg_proc AS p2
117 WHERE p1.oid < p2.oid AND
118 p1.prosrc = p2.prosrc AND
119 p1.prolang = 12 AND p2.prolang = 12 AND
120 (p1.prokind != 'a' OR p2.prokind != 'a') AND
121 (p1.prolang != p2.prolang OR
122 p1.prokind != p2.prokind OR
123 p1.prosecdef != p2.prosecdef OR
124 p1.proleakproof != p2.proleakproof OR
125 p1.proisstrict != p2.proisstrict OR
126 p1.proretset != p2.proretset OR
127 p1.provolatile != p2.provolatile OR
128 p1.pronargs != p2.pronargs);
129 oid | proname | oid | proname
130 -----+---------+-----+---------
133 -- Look for uses of different type OIDs in the argument/result type fields
134 -- for different aliases of the same built-in function.
135 -- This indicates that the types are being presumed to be binary-equivalent,
136 -- or that the built-in function is prepared to deal with different types.
137 -- That's not wrong, necessarily, but we make lists of all the types being
138 -- so treated. Note that the expected output of this part of the test will
139 -- need to be modified whenever new pairs of types are made binary-equivalent,
140 -- or when new polymorphic built-in functions are added!
141 -- Note: ignore aggregate functions here, since they all point to the same
142 -- dummy built-in function. Likewise, ignore range and multirange constructor
144 SELECT DISTINCT p1.prorettype::regtype, p2.prorettype::regtype
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 p1.prokind != 'a' AND p2.prokind != 'a' AND
150 p1.prosrc NOT LIKE E'range\\_constructor_' AND
151 p2.prosrc NOT LIKE E'range\\_constructor_' AND
152 p1.prosrc NOT LIKE E'multirange\\_constructor_' AND
153 p2.prosrc NOT LIKE E'multirange\\_constructor_' AND
154 (p1.prorettype < p2.prorettype)
156 prorettype | prorettype
157 -----------------------------+--------------------------
159 text | character varying
160 timestamp without time zone | timestamp with time zone
161 txid_snapshot | pg_snapshot
164 SELECT DISTINCT p1.proargtypes[0]::regtype, p2.proargtypes[0]::regtype
165 FROM pg_proc AS p1, pg_proc AS p2
166 WHERE p1.oid != p2.oid AND
167 p1.prosrc = p2.prosrc AND
168 p1.prolang = 12 AND p2.prolang = 12 AND
169 p1.prokind != 'a' AND p2.prokind != 'a' AND
170 p1.prosrc NOT LIKE E'range\\_constructor_' AND
171 p2.prosrc NOT LIKE E'range\\_constructor_' AND
172 p1.prosrc NOT LIKE E'multirange\\_constructor_' AND
173 p2.prosrc NOT LIKE E'multirange\\_constructor_' AND
174 (p1.proargtypes[0] < p2.proargtypes[0])
176 proargtypes | proargtypes
177 -----------------------------+--------------------------
180 text | character varying
181 timestamp without time zone | timestamp with time zone
183 txid_snapshot | pg_snapshot
186 SELECT DISTINCT p1.proargtypes[1]::regtype, p2.proargtypes[1]::regtype
187 FROM pg_proc AS p1, pg_proc AS p2
188 WHERE p1.oid != p2.oid AND
189 p1.prosrc = p2.prosrc AND
190 p1.prolang = 12 AND p2.prolang = 12 AND
191 p1.prokind != 'a' AND p2.prokind != 'a' AND
192 p1.prosrc NOT LIKE E'range\\_constructor_' AND
193 p2.prosrc NOT LIKE E'range\\_constructor_' AND
194 p1.prosrc NOT LIKE E'multirange\\_constructor_' AND
195 p2.prosrc NOT LIKE E'multirange\\_constructor_' AND
196 (p1.proargtypes[1] < p2.proargtypes[1])
198 proargtypes | proargtypes
199 -----------------------------+--------------------------
201 timestamp without time zone | timestamp with time zone
203 txid_snapshot | pg_snapshot
206 SELECT DISTINCT p1.proargtypes[2]::regtype, p2.proargtypes[2]::regtype
207 FROM pg_proc AS p1, pg_proc AS p2
208 WHERE p1.oid != p2.oid AND
209 p1.prosrc = p2.prosrc AND
210 p1.prolang = 12 AND p2.prolang = 12 AND
211 p1.prokind != 'a' AND p2.prokind != 'a' AND
212 (p1.proargtypes[2] < p2.proargtypes[2])
214 proargtypes | proargtypes
215 -----------------------------+--------------------------
216 timestamp without time zone | timestamp with time zone
219 SELECT DISTINCT p1.proargtypes[3]::regtype, p2.proargtypes[3]::regtype
220 FROM pg_proc AS p1, pg_proc AS p2
221 WHERE p1.oid != p2.oid AND
222 p1.prosrc = p2.prosrc AND
223 p1.prolang = 12 AND p2.prolang = 12 AND
224 p1.prokind != 'a' AND p2.prokind != 'a' AND
225 (p1.proargtypes[3] < p2.proargtypes[3])
227 proargtypes | proargtypes
228 -----------------------------+--------------------------
229 timestamp without time zone | timestamp with time zone
232 SELECT DISTINCT p1.proargtypes[4]::regtype, p2.proargtypes[4]::regtype
233 FROM pg_proc AS p1, pg_proc AS p2
234 WHERE p1.oid != p2.oid AND
235 p1.prosrc = p2.prosrc AND
236 p1.prolang = 12 AND p2.prolang = 12 AND
237 p1.prokind != 'a' AND p2.prokind != 'a' AND
238 (p1.proargtypes[4] < p2.proargtypes[4])
240 proargtypes | proargtypes
241 -------------+-------------
244 SELECT DISTINCT p1.proargtypes[5]::regtype, p2.proargtypes[5]::regtype
245 FROM pg_proc AS p1, pg_proc AS p2
246 WHERE p1.oid != p2.oid AND
247 p1.prosrc = p2.prosrc AND
248 p1.prolang = 12 AND p2.prolang = 12 AND
249 p1.prokind != 'a' AND p2.prokind != 'a' AND
250 (p1.proargtypes[5] < p2.proargtypes[5])
252 proargtypes | proargtypes
253 -------------+-------------
256 SELECT DISTINCT p1.proargtypes[6]::regtype, p2.proargtypes[6]::regtype
257 FROM pg_proc AS p1, pg_proc AS p2
258 WHERE p1.oid != p2.oid AND
259 p1.prosrc = p2.prosrc AND
260 p1.prolang = 12 AND p2.prolang = 12 AND
261 p1.prokind != 'a' AND p2.prokind != 'a' AND
262 (p1.proargtypes[6] < p2.proargtypes[6])
264 proargtypes | proargtypes
265 -------------+-------------
268 SELECT DISTINCT p1.proargtypes[7]::regtype, p2.proargtypes[7]::regtype
269 FROM pg_proc AS p1, pg_proc AS p2
270 WHERE p1.oid != p2.oid AND
271 p1.prosrc = p2.prosrc AND
272 p1.prolang = 12 AND p2.prolang = 12 AND
273 p1.prokind != 'a' AND p2.prokind != 'a' AND
274 (p1.proargtypes[7] < p2.proargtypes[7])
276 proargtypes | proargtypes
277 -------------+-------------
280 -- Look for functions that return type "internal" and do not have any
281 -- "internal" argument. Such a function would be a security hole since
282 -- it might be used to call an internal function from an SQL command.
283 -- As of 7.3 this query should find only internal_in, which is safe because
284 -- it always throws an error when called.
285 SELECT p1.oid, p1.proname
287 WHERE p1.prorettype = 'internal'::regtype AND NOT
288 'internal'::regtype = ANY (p1.proargtypes);
294 -- Look for functions that return a polymorphic type and do not have any
295 -- polymorphic argument. Calls of such functions would be unresolvable
296 -- at parse time. As of 9.6 this query should find only some input functions
297 -- and GiST support functions associated with these pseudotypes.
298 SELECT p1.oid, p1.proname
300 WHERE p1.prorettype IN
301 ('anyelement'::regtype, 'anyarray'::regtype, 'anynonarray'::regtype,
304 ('anyelement'::regtype = ANY (p1.proargtypes) OR
305 'anyarray'::regtype = ANY (p1.proargtypes) OR
306 'anynonarray'::regtype = ANY (p1.proargtypes) OR
307 'anyenum'::regtype = ANY (p1.proargtypes) OR
308 'anyrange'::regtype = ANY (p1.proargtypes) OR
309 'anymultirange'::regtype = ANY (p1.proargtypes))
312 ------+----------------
317 2777 | anynonarray_in
324 -- anyrange and anymultirange are tighter than the rest, can only resolve
326 SELECT p1.oid, p1.proname
328 WHERE p1.prorettype IN ('anyrange'::regtype, 'anymultirange'::regtype)
330 ('anyrange'::regtype = ANY (p1.proargtypes) OR
331 'anymultirange'::regtype = ANY (p1.proargtypes))
334 ------+------------------
335 4229 | anymultirange_in
338 4233 | multirange_recv
339 3876 | range_gist_union
344 -- similarly for the anycompatible family
345 SELECT p1.oid, p1.proname
347 WHERE p1.prorettype IN
348 ('anycompatible'::regtype, 'anycompatiblearray'::regtype,
349 'anycompatiblenonarray'::regtype)
351 ('anycompatible'::regtype = ANY (p1.proargtypes) OR
352 'anycompatiblearray'::regtype = ANY (p1.proargtypes) OR
353 'anycompatiblenonarray'::regtype = ANY (p1.proargtypes) OR
354 'anycompatiblerange'::regtype = ANY (p1.proargtypes))
357 ------+--------------------------
358 5086 | anycompatible_in
359 5088 | anycompatiblearray_in
360 5090 | anycompatiblearray_recv
361 5092 | anycompatiblenonarray_in
364 SELECT p1.oid, p1.proname
366 WHERE p1.prorettype = 'anycompatiblerange'::regtype
368 'anycompatiblerange'::regtype = ANY (p1.proargtypes)
371 ------+-----------------------
372 5094 | anycompatiblerange_in
375 -- Look for functions that accept cstring and are neither datatype input
376 -- functions nor encoding conversion functions. It's almost never a good
377 -- idea to use cstring input for a function meant to be called from SQL;
378 -- text should be used instead, because cstring lacks suitable casts.
379 -- As of 9.6 this query should find only cstring_out and cstring_send.
380 -- However, we must manually exclude shell_in, which might or might not be
381 -- rejected by the EXISTS clause depending on whether there are currently
383 SELECT p1.oid, p1.proname
385 WHERE 'cstring'::regtype = ANY (p1.proargtypes)
386 AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typinput = p1.oid)
387 AND NOT EXISTS(SELECT 1 FROM pg_conversion WHERE conproc = p1.oid)
388 AND p1.oid != 'shell_in(cstring)'::regprocedure
391 ------+--------------
396 -- Likewise, look for functions that return cstring and aren't datatype output
397 -- functions nor typmod output functions.
398 -- As of 9.6 this query should find only cstring_in and cstring_recv.
399 -- However, we must manually exclude shell_out.
400 SELECT p1.oid, p1.proname
402 WHERE p1.prorettype = 'cstring'::regtype
403 AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typoutput = p1.oid)
404 AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typmodout = p1.oid)
405 AND p1.oid != 'shell_out(void)'::regprocedure
408 ------+--------------
413 -- Check for length inconsistencies between the various argument-info arrays.
414 SELECT p1.oid, p1.proname
416 WHERE proallargtypes IS NOT NULL AND
417 array_length(proallargtypes,1) < array_length(proargtypes,1);
422 SELECT p1.oid, p1.proname
424 WHERE proargmodes IS NOT NULL AND
425 array_length(proargmodes,1) < array_length(proargtypes,1);
430 SELECT p1.oid, p1.proname
432 WHERE proargnames IS NOT NULL AND
433 array_length(proargnames,1) < array_length(proargtypes,1);
438 SELECT p1.oid, p1.proname
440 WHERE proallargtypes IS NOT NULL AND proargmodes IS NOT NULL AND
441 array_length(proallargtypes,1) <> array_length(proargmodes,1);
446 SELECT p1.oid, p1.proname
448 WHERE proallargtypes IS NOT NULL AND proargnames IS NOT NULL AND
449 array_length(proallargtypes,1) <> array_length(proargnames,1);
454 SELECT p1.oid, p1.proname
456 WHERE proargmodes IS NOT NULL AND proargnames IS NOT NULL AND
457 array_length(proargmodes,1) <> array_length(proargnames,1);
462 -- Check that proallargtypes matches proargtypes
463 SELECT p1.oid, p1.proname, p1.proargtypes, p1.proallargtypes, p1.proargmodes
465 WHERE proallargtypes IS NOT NULL AND
466 ARRAY(SELECT unnest(proargtypes)) <>
467 ARRAY(SELECT proallargtypes[i]
468 FROM generate_series(1, array_length(proallargtypes, 1)) g(i)
469 WHERE proargmodes IS NULL OR proargmodes[i] IN ('i', 'b', 'v'));
470 oid | proname | proargtypes | proallargtypes | proargmodes
471 -----+---------+-------------+----------------+-------------
474 -- Check for prosupport functions with the wrong signature
475 SELECT p1.oid, p1.proname, p2.oid, p2.proname
476 FROM pg_proc AS p1, pg_proc AS p2
477 WHERE p2.oid = p1.prosupport AND
478 (p2.prorettype != 'internal'::regtype OR p2.proretset OR p2.pronargs != 1
479 OR p2.proargtypes[0] != 'internal'::regtype);
480 oid | proname | oid | proname
481 -----+---------+-----+---------
484 -- Insist that all built-in pg_proc entries have descriptions
485 SELECT p1.oid, p1.proname
486 FROM pg_proc as p1 LEFT JOIN pg_description as d
487 ON p1.tableoid = d.classoid and p1.oid = d.objoid and d.objsubid = 0
488 WHERE d.classoid IS NULL AND p1.oid <= 9999;
493 -- List of built-in leakproof functions
495 -- Leakproof functions should only be added after carefully
496 -- scrutinizing all possibly executed codepaths for possible
497 -- information leaks. Don't add functions here unless you know what a
498 -- leakproof function is. If unsure, don't mark it as such.
499 -- temporarily disable fancy output, so catalog changes create less diff noise
501 SELECT p1.oid::regprocedure
502 FROM pg_proc p1 JOIN pg_namespace pn
503 ON pronamespace = pn.oid
504 WHERE nspname = 'pg_catalog' AND proleakproof
506 boollt(boolean,boolean)
507 boolgt(boolean,boolean)
508 booleq(boolean,boolean)
509 chareq("char","char")
511 int2eq(smallint,smallint)
512 int2lt(smallint,smallint)
513 int4eq(integer,integer)
514 int4lt(integer,integer)
518 charne("char","char")
519 charle("char","char")
520 chargt("char","char")
521 charge("char","char")
522 boolne(boolean,boolean)
523 int4ne(integer,integer)
524 int2ne(smallint,smallint)
525 int2gt(smallint,smallint)
526 int4gt(integer,integer)
527 int2le(smallint,smallint)
528 int4le(integer,integer)
529 int4ge(integer,integer)
530 int2ge(smallint,smallint)
532 int24eq(smallint,integer)
533 int42eq(integer,smallint)
534 int24lt(smallint,integer)
535 int42lt(integer,smallint)
536 int24gt(smallint,integer)
537 int42gt(integer,smallint)
538 int24ne(smallint,integer)
539 int42ne(integer,smallint)
540 int24le(smallint,integer)
541 int42le(integer,smallint)
542 int24ge(smallint,integer)
543 int42ge(integer,smallint)
548 nameeqtext(name,text)
549 namelttext(name,text)
550 nameletext(name,text)
551 namegetext(name,text)
552 namegttext(name,text)
553 namenetext(name,text)
554 btnametextcmp(name,text)
555 texteqname(text,name)
556 textltname(text,name)
557 textlename(text,name)
558 textgename(text,name)
559 textgtname(text,name)
560 textnename(text,name)
561 bttextnamecmp(text,name)
568 float8eq(double precision,double precision)
569 float8ne(double precision,double precision)
570 float8lt(double precision,double precision)
571 float8le(double precision,double precision)
572 float8gt(double precision,double precision)
573 float8ge(double precision,double precision)
574 float48eq(real,double precision)
575 float48ne(real,double precision)
576 float48lt(real,double precision)
577 float48le(real,double precision)
578 float48gt(real,double precision)
579 float48ge(real,double precision)
580 float84eq(double precision,real)
581 float84ne(double precision,real)
582 float84lt(double precision,real)
583 float84le(double precision,real)
584 float84gt(double precision,real)
585 float84ge(double precision,real)
590 btint2cmp(smallint,smallint)
591 btint4cmp(integer,integer)
592 btfloat4cmp(real,real)
593 btfloat8cmp(double precision,double precision)
595 btcharcmp("char","char")
598 cash_cmp(money,money)
599 btoidvectorcmp(oidvector,oidvector)
603 text_larger(text,text)
604 text_smaller(text,text)
605 int8eq(bigint,bigint)
606 int8ne(bigint,bigint)
607 int8lt(bigint,bigint)
608 int8gt(bigint,bigint)
609 int8le(bigint,bigint)
610 int8ge(bigint,bigint)
611 int84eq(bigint,integer)
612 int84ne(bigint,integer)
613 int84lt(bigint,integer)
614 int84gt(bigint,integer)
615 int84le(bigint,integer)
616 int84ge(bigint,integer)
619 oidvectorne(oidvector,oidvector)
626 oidvectorlt(oidvector,oidvector)
627 oidvectorle(oidvector,oidvector)
628 oidvectoreq(oidvector,oidvector)
629 oidvectorge(oidvector,oidvector)
630 oidvectorgt(oidvector,oidvector)
638 macaddr_eq(macaddr,macaddr)
639 macaddr_lt(macaddr,macaddr)
640 macaddr_le(macaddr,macaddr)
641 macaddr_gt(macaddr,macaddr)
642 macaddr_ge(macaddr,macaddr)
643 macaddr_ne(macaddr,macaddr)
644 macaddr_cmp(macaddr,macaddr)
645 btint8cmp(bigint,bigint)
646 int48eq(integer,bigint)
647 int48ne(integer,bigint)
648 int48lt(integer,bigint)
649 int48gt(integer,bigint)
650 int48le(integer,bigint)
651 int48ge(integer,bigint)
658 network_eq(inet,inet)
659 network_lt(inet,inet)
660 network_le(inet,inet)
661 network_gt(inet,inet)
662 network_ge(inet,inet)
663 network_ne(inet,inet)
664 network_cmp(inet,inet)
666 bpchareq(character,character)
667 bpcharlt(character,character)
668 bpcharle(character,character)
669 bpchargt(character,character)
670 bpcharge(character,character)
671 bpcharne(character,character)
672 bpchar_larger(character,character)
673 bpchar_smaller(character,character)
674 bpcharcmp(character,character)
682 time_lt(time without time zone,time without time zone)
683 time_le(time without time zone,time without time zone)
684 time_gt(time without time zone,time without time zone)
685 time_ge(time without time zone,time without time zone)
686 time_ne(time without time zone,time without time zone)
687 time_cmp(time without time zone,time without time zone)
688 time_eq(time without time zone,time without time zone)
689 timestamptz_eq(timestamp with time zone,timestamp with time zone)
690 timestamptz_ne(timestamp with time zone,timestamp with time zone)
691 timestamptz_lt(timestamp with time zone,timestamp with time zone)
692 timestamptz_le(timestamp with time zone,timestamp with time zone)
693 timestamptz_ge(timestamp with time zone,timestamp with time zone)
694 timestamptz_gt(timestamp with time zone,timestamp with time zone)
695 interval_eq(interval,interval)
696 interval_ne(interval,interval)
697 interval_lt(interval,interval)
698 interval_le(interval,interval)
699 interval_ge(interval,interval)
700 interval_gt(interval,interval)
701 charlt("char","char")
705 timestamptz_cmp(timestamp with time zone,timestamp with time zone)
706 interval_cmp(interval,interval)
707 xideqint4(xid,integer)
708 timetz_eq(time with time zone,time with time zone)
709 timetz_ne(time with time zone,time with time zone)
710 timetz_lt(time with time zone,time with time zone)
711 timetz_le(time with time zone,time with time zone)
712 timetz_ge(time with time zone,time with time zone)
713 timetz_gt(time with time zone,time with time zone)
714 timetz_cmp(time with time zone,time with time zone)
715 "interval"(time without time zone)
716 name(character varying)
718 circle_eq(circle,circle)
719 circle_ne(circle,circle)
720 circle_lt(circle,circle)
721 circle_gt(circle,circle)
722 circle_le(circle,circle)
723 circle_ge(circle,circle)
738 varbiteq(bit varying,bit varying)
739 varbitne(bit varying,bit varying)
740 varbitge(bit varying,bit varying)
741 varbitgt(bit varying,bit varying)
742 varbitle(bit varying,bit varying)
743 varbitlt(bit varying,bit varying)
744 varbitcmp(bit varying,bit varying)
745 boolle(boolean,boolean)
746 boolge(boolean,boolean)
747 btboolcmp(boolean,boolean)
750 "numeric"(double precision)
753 int28eq(smallint,bigint)
754 int28ne(smallint,bigint)
755 int28lt(smallint,bigint)
756 int28gt(smallint,bigint)
757 int28le(smallint,bigint)
758 int28ge(smallint,bigint)
759 int82eq(bigint,smallint)
760 int82ne(bigint,smallint)
761 int82lt(bigint,smallint)
762 int82gt(bigint,smallint)
763 int82le(bigint,smallint)
764 int82ge(bigint,smallint)
771 byteacmp(bytea,bytea)
772 timestamp_cmp(timestamp without time zone,timestamp without time zone)
773 timestamp_eq(timestamp without time zone,timestamp without time zone)
774 timestamp_ne(timestamp without time zone,timestamp without time zone)
775 timestamp_lt(timestamp without time zone,timestamp without time zone)
776 timestamp_le(timestamp without time zone,timestamp without time zone)
777 timestamp_ge(timestamp without time zone,timestamp without time zone)
778 timestamp_gt(timestamp without time zone,timestamp without time zone)
779 text_pattern_lt(text,text)
780 text_pattern_le(text,text)
781 text_pattern_ge(text,text)
782 text_pattern_gt(text,text)
783 bttext_pattern_cmp(text,text)
784 bpchar_pattern_lt(character,character)
785 bpchar_pattern_le(character,character)
786 bpchar_pattern_ge(character,character)
787 bpchar_pattern_gt(character,character)
788 btbpchar_pattern_cmp(character,character)
789 btint48cmp(integer,bigint)
790 btint84cmp(bigint,integer)
791 btint24cmp(smallint,integer)
792 btint42cmp(integer,smallint)
793 btint28cmp(smallint,bigint)
794 btint82cmp(bigint,smallint)
795 btfloat48cmp(real,double precision)
796 btfloat84cmp(double precision,real)
813 pg_lsn_lt(pg_lsn,pg_lsn)
814 pg_lsn_le(pg_lsn,pg_lsn)
815 pg_lsn_eq(pg_lsn,pg_lsn)
816 pg_lsn_ge(pg_lsn,pg_lsn)
817 pg_lsn_gt(pg_lsn,pg_lsn)
818 pg_lsn_ne(pg_lsn,pg_lsn)
819 pg_lsn_cmp(pg_lsn,pg_lsn)
821 xidneqint4(xid,integer)
827 starts_with(text,text)
828 macaddr8_eq(macaddr8,macaddr8)
829 macaddr8_lt(macaddr8,macaddr8)
830 macaddr8_le(macaddr8,macaddr8)
831 macaddr8_gt(macaddr8,macaddr8)
832 macaddr8_ge(macaddr8,macaddr8)
833 macaddr8_ne(macaddr8,macaddr8)
834 macaddr8_cmp(macaddr8,macaddr8)
843 -- restore normal output mode
845 -- List of functions used by libpq's fe-lobj.c
847 -- If the output of this query changes, you probably broke libpq.
848 -- lo_initialize() assumes that there will be at most one match for
850 select proname, oid from pg_catalog.pg_proc
865 and pronamespace = (select oid from pg_catalog.pg_namespace
866 where nspname = 'pg_catalog')
869 ---------------+------
885 -- Check that all immutable functions are marked parallel safe
886 SELECT p1.oid, p1.proname
888 WHERE provolatile = 'i' AND proparallel = 'u';
893 -- **************** pg_cast ****************
894 -- Catch bogus values in pg_cast columns (other than cases detected by
898 WHERE castsource = 0 OR casttarget = 0 OR castcontext NOT IN ('e', 'a', 'i')
899 OR castmethod NOT IN ('f', 'b' ,'i');
900 oid | castsource | casttarget | castfunc | castcontext | castmethod
901 -----+------------+------------+----------+-------------+------------
904 -- Check that castfunc is nonzero only for cast methods that need a function,
905 -- and zero otherwise
908 WHERE (castmethod = 'f' AND castfunc = 0)
909 OR (castmethod IN ('b', 'i') AND castfunc <> 0);
910 oid | castsource | casttarget | castfunc | castcontext | castmethod
911 -----+------------+------------+----------+-------------+------------
914 -- Look for casts to/from the same type that aren't length coercion functions.
915 -- (We assume they are length coercions if they take multiple arguments.)
916 -- Such entries are not necessarily harmful, but they are useless.
919 WHERE castsource = casttarget AND castfunc = 0;
920 oid | castsource | casttarget | castfunc | castcontext | castmethod
921 -----+------------+------------+----------+-------------+------------
925 FROM pg_cast c, pg_proc p
926 WHERE c.castfunc = p.oid AND p.pronargs < 2 AND castsource = casttarget;
927 oid | castsource | casttarget | castfunc | castcontext | castmethod
928 -----+------------+------------+----------+-------------+------------
931 -- Look for cast functions that don't have the right signature. The
932 -- argument and result types in pg_proc must be the same as, or binary
933 -- compatible with, what it says in pg_cast.
934 -- As a special case, we allow casts from CHAR(n) that use functions
935 -- declared to take TEXT. This does not pass the binary-coercibility test
936 -- because CHAR(n)-to-TEXT normally invokes rtrim(). However, the results
937 -- are the same, so long as the function is one that ignores trailing blanks.
939 FROM pg_cast c, pg_proc p
940 WHERE c.castfunc = p.oid AND
941 (p.pronargs < 1 OR p.pronargs > 3
942 OR NOT (binary_coercible(c.castsource, p.proargtypes[0])
943 OR (c.castsource = 'character'::regtype AND
944 p.proargtypes[0] = 'text'::regtype))
945 OR NOT binary_coercible(p.prorettype, c.casttarget));
946 oid | castsource | casttarget | castfunc | castcontext | castmethod
947 -----+------------+------------+----------+-------------+------------
951 FROM pg_cast c, pg_proc p
952 WHERE c.castfunc = p.oid AND
953 ((p.pronargs > 1 AND p.proargtypes[1] != 'int4'::regtype) OR
954 (p.pronargs > 2 AND p.proargtypes[2] != 'bool'::regtype));
955 oid | castsource | casttarget | castfunc | castcontext | castmethod
956 -----+------------+------------+----------+-------------+------------
959 -- Look for binary compatible casts that do not have the reverse
960 -- direction registered as well, or where the reverse direction is not
961 -- also binary compatible. This is legal, but usually not intended.
962 -- As of 7.4, this finds the casts from text and varchar to bpchar, because
963 -- those are binary-compatible while the reverse way goes through rtrim().
964 -- As of 8.2, this finds the cast from cidr to inet, because that is a
965 -- trivial binary coercion while the other way goes through inet_to_cidr().
966 -- As of 8.3, this finds the casts from xml to text, varchar, and bpchar,
967 -- because those are binary-compatible while the reverse goes through
968 -- texttoxml(), which does an XML syntax check.
969 -- As of 9.1, this finds the cast from pg_node_tree to text, which we
970 -- intentionally do not provide a reverse pathway for.
971 SELECT castsource::regtype, casttarget::regtype, castfunc, castcontext
973 WHERE c.castmethod = 'b' AND
974 NOT EXISTS (SELECT 1 FROM pg_cast k
975 WHERE k.castmethod = 'b' AND
976 k.castsource = c.casttarget AND
977 k.casttarget = c.castsource);
978 castsource | casttarget | castfunc | castcontext
979 -------------------+-------------------+----------+-------------
980 text | character | 0 | i
981 character varying | character | 0 | i
982 pg_node_tree | text | 0 | i
983 pg_ndistinct | bytea | 0 | i
984 pg_dependencies | bytea | 0 | i
985 pg_mcv_list | bytea | 0 | i
988 xml | character varying | 0 | a
989 xml | character | 0 | a
992 -- **************** pg_conversion ****************
993 -- Look for illegal values in pg_conversion fields.
994 SELECT p1.oid, p1.conname
995 FROM pg_conversion as p1
996 WHERE p1.conproc = 0 OR
997 pg_encoding_to_char(conforencoding) = '' OR
998 pg_encoding_to_char(contoencoding) = '';
1003 -- Look for conprocs that don't have the expected signature.
1004 SELECT p.oid, p.proname, c.oid, c.conname
1005 FROM pg_proc p, pg_conversion c
1006 WHERE p.oid = c.conproc AND
1007 (p.prorettype != 'int4'::regtype OR p.proretset OR
1009 p.proargtypes[0] != 'int4'::regtype OR
1010 p.proargtypes[1] != 'int4'::regtype OR
1011 p.proargtypes[2] != 'cstring'::regtype OR
1012 p.proargtypes[3] != 'internal'::regtype OR
1013 p.proargtypes[4] != 'int4'::regtype OR
1014 p.proargtypes[5] != 'bool'::regtype);
1015 oid | proname | oid | conname
1016 -----+---------+-----+---------
1019 -- Check for conprocs that don't perform the specific conversion that
1020 -- pg_conversion alleges they do, by trying to invoke each conversion
1021 -- on some simple ASCII data. (The conproc should throw an error if
1022 -- it doesn't accept the encodings that are passed to it.)
1023 -- Unfortunately, we can't test non-default conprocs this way, because
1024 -- there is no way to ask convert() to invoke them, and we cannot call
1025 -- them directly from SQL. But there are no non-default built-in
1026 -- conversions anyway.
1027 -- (Similarly, this doesn't cope with any search path issues.)
1028 SELECT p1.oid, p1.conname
1029 FROM pg_conversion as p1
1030 WHERE condefault AND
1031 convert('ABC'::bytea, pg_encoding_to_char(conforencoding),
1032 pg_encoding_to_char(contoencoding)) != 'ABC';
1037 -- **************** pg_operator ****************
1038 -- Look for illegal values in pg_operator fields.
1039 SELECT p1.oid, p1.oprname
1040 FROM pg_operator as p1
1041 WHERE (p1.oprkind != 'b' AND p1.oprkind != 'l') OR
1042 p1.oprresult = 0 OR p1.oprcode = 0;
1047 -- Look for missing or unwanted operand types
1048 SELECT p1.oid, p1.oprname
1049 FROM pg_operator as p1
1050 WHERE (p1.oprleft = 0 and p1.oprkind != 'l') OR
1051 (p1.oprleft != 0 and p1.oprkind = 'l') OR
1057 -- Look for conflicting operator definitions (same names and input datatypes).
1058 SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
1059 FROM pg_operator AS p1, pg_operator AS p2
1060 WHERE p1.oid != p2.oid AND
1061 p1.oprname = p2.oprname AND
1062 p1.oprkind = p2.oprkind AND
1063 p1.oprleft = p2.oprleft AND
1064 p1.oprright = p2.oprright;
1065 oid | oprcode | oid | oprcode
1066 -----+---------+-----+---------
1069 -- Look for commutative operators that don't commute.
1070 -- DEFINITIONAL NOTE: If A.oprcom = B, then x A y has the same result as y B x.
1071 -- We expect that B will always say that B.oprcom = A as well; that's not
1072 -- inherently essential, but it would be inefficient not to mark it so.
1073 SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
1074 FROM pg_operator AS p1, pg_operator AS p2
1075 WHERE p1.oprcom = p2.oid AND
1076 (p1.oprkind != 'b' OR
1077 p1.oprleft != p2.oprright OR
1078 p1.oprright != p2.oprleft OR
1079 p1.oprresult != p2.oprresult OR
1080 p1.oid != p2.oprcom);
1081 oid | oprcode | oid | oprcode
1082 -----+---------+-----+---------
1085 -- Look for negatory operators that don't agree.
1086 -- DEFINITIONAL NOTE: If A.oprnegate = B, then both A and B must yield
1087 -- boolean results, and (x A y) == ! (x B y), or the equivalent for
1088 -- single-operand operators.
1089 -- We expect that B will always say that B.oprnegate = A as well; that's not
1090 -- inherently essential, but it would be inefficient not to mark it so.
1091 -- Also, A and B had better not be the same operator.
1092 SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
1093 FROM pg_operator AS p1, pg_operator AS p2
1094 WHERE p1.oprnegate = p2.oid AND
1095 (p1.oprkind != p2.oprkind OR
1096 p1.oprleft != p2.oprleft OR
1097 p1.oprright != p2.oprright OR
1098 p1.oprresult != 'bool'::regtype OR
1099 p2.oprresult != 'bool'::regtype OR
1100 p1.oid != p2.oprnegate OR
1102 oid | oprcode | oid | oprcode
1103 -----+---------+-----+---------
1106 -- Make a list of the names of operators that are claimed to be commutator
1107 -- pairs. This list will grow over time, but before accepting a new entry
1108 -- make sure you didn't link the wrong operators.
1109 SELECT DISTINCT o1.oprname AS op1, o2.oprname AS op2
1110 FROM pg_operator o1, pg_operator o2
1111 WHERE o1.oprcom = o2.oid AND o1.oprname <= o2.oprname
1146 -- Likewise for negator pairs.
1147 SELECT DISTINCT o1.oprname AS op1, o2.oprname AS op2
1148 FROM pg_operator o1, pg_operator o2
1149 WHERE o1.oprnegate = o2.oid AND o1.oprname <= o2.oprname
1168 -- A mergejoinable or hashjoinable operator must be binary, must return
1169 -- boolean, and must have a commutator (itself, unless it's a cross-type
1171 SELECT p1.oid, p1.oprname FROM pg_operator AS p1
1172 WHERE (p1.oprcanmerge OR p1.oprcanhash) AND NOT
1173 (p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND p1.oprcom != 0);
1178 -- What's more, the commutator had better be mergejoinable/hashjoinable too.
1179 SELECT p1.oid, p1.oprname, p2.oid, p2.oprname
1180 FROM pg_operator AS p1, pg_operator AS p2
1181 WHERE p1.oprcom = p2.oid AND
1182 (p1.oprcanmerge != p2.oprcanmerge OR
1183 p1.oprcanhash != p2.oprcanhash);
1184 oid | oprname | oid | oprname
1185 -----+---------+-----+---------
1188 -- Mergejoinable operators should appear as equality members of btree index
1190 SELECT p1.oid, p1.oprname
1191 FROM pg_operator AS p1
1192 WHERE p1.oprcanmerge AND NOT EXISTS
1193 (SELECT 1 FROM pg_amop
1194 WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND
1195 amopopr = p1.oid AND amopstrategy = 3);
1200 -- And the converse.
1201 SELECT p1.oid, p1.oprname, p.amopfamily
1202 FROM pg_operator AS p1, pg_amop p
1203 WHERE amopopr = p1.oid
1204 AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree')
1205 AND amopstrategy = 3
1206 AND NOT p1.oprcanmerge;
1207 oid | oprname | amopfamily
1208 -----+---------+------------
1211 -- Hashable operators should appear as members of hash index opfamilies.
1212 SELECT p1.oid, p1.oprname
1213 FROM pg_operator AS p1
1214 WHERE p1.oprcanhash AND NOT EXISTS
1215 (SELECT 1 FROM pg_amop
1216 WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND
1217 amopopr = p1.oid AND amopstrategy = 1);
1222 -- And the converse.
1223 SELECT p1.oid, p1.oprname, p.amopfamily
1224 FROM pg_operator AS p1, pg_amop p
1225 WHERE amopopr = p1.oid
1226 AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash')
1227 AND NOT p1.oprcanhash;
1228 oid | oprname | amopfamily
1229 -----+---------+------------
1232 -- Check that each operator defined in pg_operator matches its oprcode entry
1233 -- in pg_proc. Easiest to do this separately for each oprkind.
1234 SELECT p1.oid, p1.oprname, p2.oid, p2.proname
1235 FROM pg_operator AS p1, pg_proc AS p2
1236 WHERE p1.oprcode = p2.oid AND
1237 p1.oprkind = 'b' AND
1239 OR NOT binary_coercible(p2.prorettype, p1.oprresult)
1240 OR NOT binary_coercible(p1.oprleft, p2.proargtypes[0])
1241 OR NOT binary_coercible(p1.oprright, p2.proargtypes[1]));
1242 oid | oprname | oid | proname
1243 -----+---------+-----+---------
1246 SELECT p1.oid, p1.oprname, p2.oid, p2.proname
1247 FROM pg_operator AS p1, pg_proc AS p2
1248 WHERE p1.oprcode = p2.oid AND
1249 p1.oprkind = 'l' AND
1251 OR NOT binary_coercible(p2.prorettype, p1.oprresult)
1252 OR NOT binary_coercible(p1.oprright, p2.proargtypes[0])
1253 OR p1.oprleft != 0);
1254 oid | oprname | oid | proname
1255 -----+---------+-----+---------
1258 -- If the operator is mergejoinable or hashjoinable, its underlying function
1259 -- should not be volatile.
1260 SELECT p1.oid, p1.oprname, p2.oid, p2.proname
1261 FROM pg_operator AS p1, pg_proc AS p2
1262 WHERE p1.oprcode = p2.oid AND
1263 (p1.oprcanmerge OR p1.oprcanhash) AND
1264 p2.provolatile = 'v';
1265 oid | oprname | oid | proname
1266 -----+---------+-----+---------
1269 -- If oprrest is set, the operator must return boolean,
1270 -- and it must link to a proc with the right signature
1271 -- to be a restriction selectivity estimator.
1272 -- The proc signature we want is: float8 proc(internal, oid, internal, int4)
1273 SELECT p1.oid, p1.oprname, p2.oid, p2.proname
1274 FROM pg_operator AS p1, pg_proc AS p2
1275 WHERE p1.oprrest = p2.oid AND
1276 (p1.oprresult != 'bool'::regtype OR
1277 p2.prorettype != 'float8'::regtype OR p2.proretset OR
1279 p2.proargtypes[0] != 'internal'::regtype OR
1280 p2.proargtypes[1] != 'oid'::regtype OR
1281 p2.proargtypes[2] != 'internal'::regtype OR
1282 p2.proargtypes[3] != 'int4'::regtype);
1283 oid | oprname | oid | proname
1284 -----+---------+-----+---------
1287 -- If oprjoin is set, the operator must be a binary boolean op,
1288 -- and it must link to a proc with the right signature
1289 -- to be a join selectivity estimator.
1290 -- The proc signature we want is: float8 proc(internal, oid, internal, int2, internal)
1291 -- (Note: the old signature with only 4 args is still allowed, but no core
1292 -- estimator should be using it.)
1293 SELECT p1.oid, p1.oprname, p2.oid, p2.proname
1294 FROM pg_operator AS p1, pg_proc AS p2
1295 WHERE p1.oprjoin = p2.oid AND
1296 (p1.oprkind != 'b' OR p1.oprresult != 'bool'::regtype OR
1297 p2.prorettype != 'float8'::regtype OR p2.proretset OR
1299 p2.proargtypes[0] != 'internal'::regtype OR
1300 p2.proargtypes[1] != 'oid'::regtype OR
1301 p2.proargtypes[2] != 'internal'::regtype OR
1302 p2.proargtypes[3] != 'int2'::regtype OR
1303 p2.proargtypes[4] != 'internal'::regtype);
1304 oid | oprname | oid | proname
1305 -----+---------+-----+---------
1308 -- Insist that all built-in pg_operator entries have descriptions
1309 SELECT p1.oid, p1.oprname
1310 FROM pg_operator as p1 LEFT JOIN pg_description as d
1311 ON p1.tableoid = d.classoid and p1.oid = d.objoid and d.objsubid = 0
1312 WHERE d.classoid IS NULL AND p1.oid <= 9999;
1317 -- Check that operators' underlying functions have suitable comments,
1318 -- namely 'implementation of XXX operator'. (Note: it's not necessary to
1319 -- put such comments into pg_proc.dat; initdb will generate them as needed.)
1320 -- In some cases involving legacy names for operators, there are multiple
1321 -- operators referencing the same pg_proc entry, so ignore operators whose
1322 -- comments say they are deprecated.
1323 -- We also have a few functions that are both operator support and meant to
1324 -- be called directly; those should have comments matching their operator.
1326 SELECT p.oid as p_oid, proname, o.oid as o_oid,
1327 pd.description as prodesc,
1328 'implementation of ' || oprname || ' operator' as expecteddesc,
1329 od.description as oprdesc
1330 FROM pg_proc p JOIN pg_operator o ON oprcode = p.oid
1331 LEFT JOIN pg_description pd ON
1332 (pd.objoid = p.oid and pd.classoid = p.tableoid and pd.objsubid = 0)
1333 LEFT JOIN pg_description od ON
1334 (od.objoid = o.oid and od.classoid = o.tableoid and od.objsubid = 0)
1337 SELECT * FROM funcdescs
1338 WHERE prodesc IS DISTINCT FROM expecteddesc
1339 AND oprdesc NOT LIKE 'deprecated%'
1340 AND prodesc IS DISTINCT FROM oprdesc;
1341 p_oid | proname | o_oid | prodesc | expecteddesc | oprdesc
1342 -------+---------+-------+---------+--------------+---------
1345 -- Show all the operator-implementation functions that have their own
1346 -- comments. This should happen only in cases where the function and
1347 -- operator syntaxes are both documented at the user level.
1348 -- This should be a pretty short list; it's mostly legacy cases.
1350 SELECT p.oid as p_oid, proname, o.oid as o_oid,
1351 pd.description as prodesc,
1352 'implementation of ' || oprname || ' operator' as expecteddesc,
1353 od.description as oprdesc
1354 FROM pg_proc p JOIN pg_operator o ON oprcode = p.oid
1355 LEFT JOIN pg_description pd ON
1356 (pd.objoid = p.oid and pd.classoid = p.tableoid and pd.objsubid = 0)
1357 LEFT JOIN pg_description od ON
1358 (od.objoid = o.oid and od.classoid = o.tableoid and od.objsubid = 0)
1361 SELECT p_oid, proname, prodesc FROM funcdescs
1362 WHERE prodesc IS DISTINCT FROM expecteddesc
1363 AND oprdesc NOT LIKE 'deprecated%'
1365 p_oid | proname | prodesc
1366 -------+-------------------------+-------------------------------------------------
1367 378 | array_append | append element onto end of array
1368 379 | array_prepend | prepend element onto front of array
1369 1035 | aclinsert | add/update ACL item
1370 1036 | aclremove | remove ACL item
1371 1037 | aclcontains | contains
1372 3217 | jsonb_extract_path | get value from jsonb with path elements
1373 3940 | jsonb_extract_path_text | get value from jsonb as text with path elements
1374 3951 | json_extract_path | get value from json with path elements
1375 3953 | json_extract_path_text | get value from json as text with path elements
1378 -- Operators that are commutator pairs should have identical volatility
1379 -- and leakproofness markings on their implementation functions.
1380 SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode
1381 FROM pg_operator AS o1, pg_operator AS o2, pg_proc AS p1, pg_proc AS p2
1382 WHERE o1.oprcom = o2.oid AND p1.oid = o1.oprcode AND p2.oid = o2.oprcode AND
1383 (p1.provolatile != p2.provolatile OR
1384 p1.proleakproof != p2.proleakproof);
1385 oid | oprcode | oid | oprcode
1386 -----+---------+-----+---------
1389 -- Likewise for negator pairs.
1390 SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode
1391 FROM pg_operator AS o1, pg_operator AS o2, pg_proc AS p1, pg_proc AS p2
1392 WHERE o1.oprnegate = o2.oid AND p1.oid = o1.oprcode AND p2.oid = o2.oprcode AND
1393 (p1.provolatile != p2.provolatile OR
1394 p1.proleakproof != p2.proleakproof);
1395 oid | oprcode | oid | oprcode
1396 -----+---------+-----+---------
1399 -- Btree comparison operators' functions should have the same volatility
1400 -- and leakproofness markings as the associated comparison support function.
1401 SELECT pp.oid::regprocedure as proc, pp.provolatile as vp, pp.proleakproof as lp,
1402 po.oid::regprocedure as opr, po.provolatile as vo, po.proleakproof as lo
1403 FROM pg_proc pp, pg_proc po, pg_operator o, pg_amproc ap, pg_amop ao
1404 WHERE pp.oid = ap.amproc AND po.oid = o.oprcode AND o.oid = ao.amopopr AND
1405 ao.amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND
1406 ao.amopfamily = ap.amprocfamily AND
1407 ao.amoplefttype = ap.amproclefttype AND
1408 ao.amoprighttype = ap.amprocrighttype AND
1409 ap.amprocnum = 1 AND
1410 (pp.provolatile != po.provolatile OR
1411 pp.proleakproof != po.proleakproof)
1413 proc | vp | lp | opr | vo | lo
1414 ------+----+----+-----+----+----
1417 -- **************** pg_aggregate ****************
1418 -- Look for illegal values in pg_aggregate fields.
1419 SELECT ctid, aggfnoid::oid
1420 FROM pg_aggregate as p1
1421 WHERE aggfnoid = 0 OR aggtransfn = 0 OR
1422 aggkind NOT IN ('n', 'o', 'h') OR
1423 aggnumdirectargs < 0 OR
1424 (aggkind = 'n' AND aggnumdirectargs > 0) OR
1425 aggfinalmodify NOT IN ('r', 's', 'w') OR
1426 aggmfinalmodify NOT IN ('r', 's', 'w') OR
1427 aggtranstype = 0 OR aggtransspace < 0 OR aggmtransspace < 0;
1432 -- Make sure the matching pg_proc entry is sensible, too.
1433 SELECT a.aggfnoid::oid, p.proname
1434 FROM pg_aggregate as a, pg_proc as p
1435 WHERE a.aggfnoid = p.oid AND
1436 (p.prokind != 'a' OR p.proretset OR p.pronargs < a.aggnumdirectargs);
1438 ----------+---------
1441 -- Make sure there are no prokind = PROKIND_AGGREGATE pg_proc entries without matches.
1444 WHERE p.prokind = 'a' AND
1445 NOT EXISTS (SELECT 1 FROM pg_aggregate a WHERE a.aggfnoid = p.oid);
1450 -- If there is no finalfn then the output type must be the transtype.
1451 SELECT a.aggfnoid::oid, p.proname
1452 FROM pg_aggregate as a, pg_proc as p
1453 WHERE a.aggfnoid = p.oid AND
1454 a.aggfinalfn = 0 AND p.prorettype != a.aggtranstype;
1456 ----------+---------
1459 -- Cross-check transfn against its entry in pg_proc.
1460 SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname
1461 FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr
1462 WHERE a.aggfnoid = p.oid AND
1463 a.aggtransfn = ptr.oid AND
1465 OR NOT (ptr.pronargs =
1466 CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1
1467 ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END)
1468 OR NOT binary_coercible(ptr.prorettype, a.aggtranstype)
1469 OR NOT binary_coercible(a.aggtranstype, ptr.proargtypes[0])
1470 OR (p.pronargs > 0 AND
1471 NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1]))
1472 OR (p.pronargs > 1 AND
1473 NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2]))
1474 OR (p.pronargs > 2 AND
1475 NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3]))
1476 -- we could carry the check further, but 3 args is enough for now
1479 aggfnoid | proname | oid | proname
1480 ----------+---------+-----+---------
1483 -- Cross-check finalfn (if present) against its entry in pg_proc.
1484 SELECT a.aggfnoid::oid, p.proname, pfn.oid, pfn.proname
1485 FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS pfn
1486 WHERE a.aggfnoid = p.oid AND
1487 a.aggfinalfn = pfn.oid AND
1489 NOT binary_coercible(pfn.prorettype, p.prorettype) OR
1490 NOT binary_coercible(a.aggtranstype, pfn.proargtypes[0]) OR
1491 CASE WHEN a.aggfinalextra THEN pfn.pronargs != p.pronargs + 1
1492 ELSE pfn.pronargs != a.aggnumdirectargs + 1 END
1493 OR (pfn.pronargs > 1 AND
1494 NOT binary_coercible(p.proargtypes[0], pfn.proargtypes[1]))
1495 OR (pfn.pronargs > 2 AND
1496 NOT binary_coercible(p.proargtypes[1], pfn.proargtypes[2]))
1497 OR (pfn.pronargs > 3 AND
1498 NOT binary_coercible(p.proargtypes[2], pfn.proargtypes[3]))
1499 -- we could carry the check further, but 4 args is enough for now
1500 OR (pfn.pronargs > 4)
1502 aggfnoid | proname | oid | proname
1503 ----------+---------+-----+---------
1506 -- If transfn is strict then either initval should be non-NULL, or
1507 -- input type should match transtype so that the first non-null input
1508 -- can be assigned as the state value.
1509 SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname
1510 FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr
1511 WHERE a.aggfnoid = p.oid AND
1512 a.aggtransfn = ptr.oid AND ptr.proisstrict AND
1513 a.agginitval IS NULL AND
1514 NOT binary_coercible(p.proargtypes[0], a.aggtranstype);
1515 aggfnoid | proname | oid | proname
1516 ----------+---------+-----+---------
1519 -- Check for inconsistent specifications of moving-aggregate columns.
1520 SELECT ctid, aggfnoid::oid
1521 FROM pg_aggregate as p1
1522 WHERE aggmtranstype != 0 AND
1523 (aggmtransfn = 0 OR aggminvtransfn = 0);
1528 SELECT ctid, aggfnoid::oid
1529 FROM pg_aggregate as p1
1530 WHERE aggmtranstype = 0 AND
1531 (aggmtransfn != 0 OR aggminvtransfn != 0 OR aggmfinalfn != 0 OR
1532 aggmtransspace != 0 OR aggminitval IS NOT NULL);
1537 -- If there is no mfinalfn then the output type must be the mtranstype.
1538 SELECT a.aggfnoid::oid, p.proname
1539 FROM pg_aggregate as a, pg_proc as p
1540 WHERE a.aggfnoid = p.oid AND
1541 a.aggmtransfn != 0 AND
1542 a.aggmfinalfn = 0 AND p.prorettype != a.aggmtranstype;
1544 ----------+---------
1547 -- Cross-check mtransfn (if present) against its entry in pg_proc.
1548 SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname
1549 FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr
1550 WHERE a.aggfnoid = p.oid AND
1551 a.aggmtransfn = ptr.oid AND
1553 OR NOT (ptr.pronargs =
1554 CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1
1555 ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END)
1556 OR NOT binary_coercible(ptr.prorettype, a.aggmtranstype)
1557 OR NOT binary_coercible(a.aggmtranstype, ptr.proargtypes[0])
1558 OR (p.pronargs > 0 AND
1559 NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1]))
1560 OR (p.pronargs > 1 AND
1561 NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2]))
1562 OR (p.pronargs > 2 AND
1563 NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3]))
1564 -- we could carry the check further, but 3 args is enough for now
1567 aggfnoid | proname | oid | proname
1568 ----------+---------+-----+---------
1571 -- Cross-check minvtransfn (if present) against its entry in pg_proc.
1572 SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname
1573 FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr
1574 WHERE a.aggfnoid = p.oid AND
1575 a.aggminvtransfn = ptr.oid AND
1577 OR NOT (ptr.pronargs =
1578 CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1
1579 ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END)
1580 OR NOT binary_coercible(ptr.prorettype, a.aggmtranstype)
1581 OR NOT binary_coercible(a.aggmtranstype, ptr.proargtypes[0])
1582 OR (p.pronargs > 0 AND
1583 NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1]))
1584 OR (p.pronargs > 1 AND
1585 NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2]))
1586 OR (p.pronargs > 2 AND
1587 NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3]))
1588 -- we could carry the check further, but 3 args is enough for now
1591 aggfnoid | proname | oid | proname
1592 ----------+---------+-----+---------
1595 -- Cross-check mfinalfn (if present) against its entry in pg_proc.
1596 SELECT a.aggfnoid::oid, p.proname, pfn.oid, pfn.proname
1597 FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS pfn
1598 WHERE a.aggfnoid = p.oid AND
1599 a.aggmfinalfn = pfn.oid AND
1601 NOT binary_coercible(pfn.prorettype, p.prorettype) OR
1602 NOT binary_coercible(a.aggmtranstype, pfn.proargtypes[0]) OR
1603 CASE WHEN a.aggmfinalextra THEN pfn.pronargs != p.pronargs + 1
1604 ELSE pfn.pronargs != a.aggnumdirectargs + 1 END
1605 OR (pfn.pronargs > 1 AND
1606 NOT binary_coercible(p.proargtypes[0], pfn.proargtypes[1]))
1607 OR (pfn.pronargs > 2 AND
1608 NOT binary_coercible(p.proargtypes[1], pfn.proargtypes[2]))
1609 OR (pfn.pronargs > 3 AND
1610 NOT binary_coercible(p.proargtypes[2], pfn.proargtypes[3]))
1611 -- we could carry the check further, but 4 args is enough for now
1612 OR (pfn.pronargs > 4)
1614 aggfnoid | proname | oid | proname
1615 ----------+---------+-----+---------
1618 -- If mtransfn is strict then either minitval should be non-NULL, or
1619 -- input type should match mtranstype so that the first non-null input
1620 -- can be assigned as the state value.
1621 SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname
1622 FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr
1623 WHERE a.aggfnoid = p.oid AND
1624 a.aggmtransfn = ptr.oid AND ptr.proisstrict AND
1625 a.aggminitval IS NULL AND
1626 NOT binary_coercible(p.proargtypes[0], a.aggmtranstype);
1627 aggfnoid | proname | oid | proname
1628 ----------+---------+-----+---------
1631 -- mtransfn and minvtransfn should have same strictness setting.
1632 SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname, iptr.oid, iptr.proname
1633 FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr, pg_proc AS iptr
1634 WHERE a.aggfnoid = p.oid AND
1635 a.aggmtransfn = ptr.oid AND
1636 a.aggminvtransfn = iptr.oid AND
1637 ptr.proisstrict != iptr.proisstrict;
1638 aggfnoid | proname | oid | proname | oid | proname
1639 ----------+---------+-----+---------+-----+---------
1642 -- Check that all combine functions have signature
1643 -- combine(transtype, transtype) returns transtype
1644 SELECT a.aggfnoid, p.proname
1645 FROM pg_aggregate as a, pg_proc as p
1646 WHERE a.aggcombinefn = p.oid AND
1648 p.prorettype != p.proargtypes[0] OR
1649 p.prorettype != p.proargtypes[1] OR
1650 NOT binary_coercible(a.aggtranstype, p.proargtypes[0]));
1652 ----------+---------
1655 -- Check that no combine function for an INTERNAL transtype is strict.
1656 SELECT a.aggfnoid, p.proname
1657 FROM pg_aggregate as a, pg_proc as p
1658 WHERE a.aggcombinefn = p.oid AND
1659 a.aggtranstype = 'internal'::regtype AND p.proisstrict;
1661 ----------+---------
1664 -- serialize/deserialize functions should be specified only for aggregates
1665 -- with transtype internal and a combine function, and we should have both
1666 -- or neither of them.
1667 SELECT aggfnoid, aggtranstype, aggserialfn, aggdeserialfn
1669 WHERE (aggserialfn != 0 OR aggdeserialfn != 0)
1670 AND (aggtranstype != 'internal'::regtype OR aggcombinefn = 0 OR
1671 aggserialfn = 0 OR aggdeserialfn = 0);
1672 aggfnoid | aggtranstype | aggserialfn | aggdeserialfn
1673 ----------+--------------+-------------+---------------
1676 -- Check that all serialization functions have signature
1677 -- serialize(internal) returns bytea
1678 -- Also insist that they be strict; it's wasteful to run them on NULLs.
1679 SELECT a.aggfnoid, p.proname
1680 FROM pg_aggregate as a, pg_proc as p
1681 WHERE a.aggserialfn = p.oid AND
1682 (p.prorettype != 'bytea'::regtype OR p.pronargs != 1 OR
1683 p.proargtypes[0] != 'internal'::regtype OR
1686 ----------+---------
1689 -- Check that all deserialization functions have signature
1690 -- deserialize(bytea, internal) returns internal
1691 -- Also insist that they be strict; it's wasteful to run them on NULLs.
1692 SELECT a.aggfnoid, p.proname
1693 FROM pg_aggregate as a, pg_proc as p
1694 WHERE a.aggdeserialfn = p.oid AND
1695 (p.prorettype != 'internal'::regtype OR p.pronargs != 2 OR
1696 p.proargtypes[0] != 'bytea'::regtype OR
1697 p.proargtypes[1] != 'internal'::regtype OR
1700 ----------+---------
1703 -- Check that aggregates which have the same transition function also have
1704 -- the same combine, serialization, and deserialization functions.
1705 -- While that isn't strictly necessary, it's fishy if they don't.
1706 SELECT a.aggfnoid, a.aggcombinefn, a.aggserialfn, a.aggdeserialfn,
1707 b.aggfnoid, b.aggcombinefn, b.aggserialfn, b.aggdeserialfn
1709 pg_aggregate a, pg_aggregate b
1711 a.aggfnoid < b.aggfnoid AND a.aggtransfn = b.aggtransfn AND
1712 (a.aggcombinefn != b.aggcombinefn OR a.aggserialfn != b.aggserialfn
1713 OR a.aggdeserialfn != b.aggdeserialfn);
1714 aggfnoid | aggcombinefn | aggserialfn | aggdeserialfn | aggfnoid | aggcombinefn | aggserialfn | aggdeserialfn
1715 ----------+--------------+-------------+---------------+----------+--------------+-------------+---------------
1718 -- Cross-check aggsortop (if present) against pg_operator.
1719 -- We expect to find entries for bool_and, bool_or, every, max, and min.
1720 SELECT DISTINCT proname, oprname
1721 FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p
1722 WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid
1725 ----------+---------
1733 -- Check datatypes match
1734 SELECT a.aggfnoid::oid, o.oid
1735 FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p
1736 WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND
1737 (oprkind != 'b' OR oprresult != 'boolean'::regtype
1738 OR oprleft != p.proargtypes[0] OR oprright != p.proargtypes[0]);
1743 -- Check operator is a suitable btree opfamily member
1744 SELECT a.aggfnoid::oid, o.oid
1745 FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p
1746 WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND
1747 NOT EXISTS(SELECT 1 FROM pg_amop
1748 WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree')
1750 AND amoplefttype = o.oprleft
1751 AND amoprighttype = o.oprright);
1756 -- Check correspondence of btree strategies and names
1757 SELECT DISTINCT proname, oprname, amopstrategy
1758 FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p,
1760 WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND
1762 amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree')
1764 proname | oprname | amopstrategy
1765 ----------+---------+--------------
1773 -- Check that there are not aggregates with the same name and different
1774 -- numbers of arguments. While not technically wrong, we have a project policy
1775 -- to avoid this because it opens the door for confusion in connection with
1776 -- ORDER BY: novices frequently put the ORDER BY in the wrong place.
1777 -- See the fate of the single-argument form of string_agg() for history.
1778 -- (Note: we don't forbid users from creating such aggregates; the policy is
1779 -- just to think twice before creating built-in aggregates like this.)
1780 -- The only aggregates that should show up here are count(x) and count(*).
1781 SELECT p1.oid::regprocedure, p2.oid::regprocedure
1782 FROM pg_proc AS p1, pg_proc AS p2
1783 WHERE p1.oid < p2.oid AND p1.proname = p2.proname AND
1784 p1.prokind = 'a' AND p2.prokind = 'a' AND
1785 array_dims(p1.proargtypes) != array_dims(p2.proargtypes)
1788 --------------+---------
1789 count("any") | count()
1792 -- For the same reason, built-in aggregates with default arguments are no good.
1795 WHERE prokind = 'a' AND proargdefaults IS NOT NULL;
1800 -- For the same reason, we avoid creating built-in variadic aggregates, except
1801 -- that variadic ordered-set aggregates are OK (since they have special syntax
1802 -- that is not subject to the misplaced ORDER BY issue).
1803 SELECT p.oid, proname
1804 FROM pg_proc AS p JOIN pg_aggregate AS a ON a.aggfnoid = p.oid
1805 WHERE prokind = 'a' AND provariadic != 0 AND a.aggkind = 'n';
1810 -- **************** pg_opfamily ****************
1811 -- Look for illegal values in pg_opfamily fields
1813 FROM pg_opfamily as p1
1814 WHERE p1.opfmethod = 0 OR p1.opfnamespace = 0;
1819 -- Look for opfamilies having no opclasses. While most validation of
1820 -- opfamilies is now handled by AM-specific amvalidate functions, that's
1821 -- driven from pg_opclass entries below, so an empty opfamily would not
1823 SELECT oid, opfname FROM pg_opfamily f
1824 WHERE NOT EXISTS (SELECT 1 FROM pg_opclass WHERE opcfamily = f.oid);
1829 -- **************** pg_opclass ****************
1830 -- Look for illegal values in pg_opclass fields
1832 FROM pg_opclass AS p1
1833 WHERE p1.opcmethod = 0 OR p1.opcnamespace = 0 OR p1.opcfamily = 0
1834 OR p1.opcintype = 0;
1839 -- opcmethod must match owning opfamily's opfmethod
1840 SELECT p1.oid, p2.oid
1841 FROM pg_opclass AS p1, pg_opfamily AS p2
1842 WHERE p1.opcfamily = p2.oid AND p1.opcmethod != p2.opfmethod;
1847 -- There should not be multiple entries in pg_opclass with opcdefault true
1848 -- and the same opcmethod/opcintype combination.
1849 SELECT p1.oid, p2.oid
1850 FROM pg_opclass AS p1, pg_opclass AS p2
1851 WHERE p1.oid != p2.oid AND
1852 p1.opcmethod = p2.opcmethod AND p1.opcintype = p2.opcintype AND
1853 p1.opcdefault AND p2.opcdefault;
1858 -- Ask access methods to validate opclasses
1859 -- (this replaces a lot of SQL-level checks that used to be done in this file)
1860 SELECT oid, opcname FROM pg_opclass WHERE NOT amvalidate(oid);
1865 -- **************** pg_am ****************
1866 -- Look for illegal values in pg_am fields
1867 SELECT p1.oid, p1.amname
1869 WHERE p1.amhandler = 0;
1874 -- Check for index amhandler functions with the wrong signature
1875 SELECT p1.oid, p1.amname, p2.oid, p2.proname
1876 FROM pg_am AS p1, pg_proc AS p2
1877 WHERE p2.oid = p1.amhandler AND p1.amtype = 'i' AND
1878 (p2.prorettype != 'index_am_handler'::regtype
1881 OR p2.proargtypes[0] != 'internal'::regtype);
1882 oid | amname | oid | proname
1883 -----+--------+-----+---------
1886 -- Check for table amhandler functions with the wrong signature
1887 SELECT p1.oid, p1.amname, p2.oid, p2.proname
1888 FROM pg_am AS p1, pg_proc AS p2
1889 WHERE p2.oid = p1.amhandler AND p1.amtype = 's' AND
1890 (p2.prorettype != 'table_am_handler'::regtype
1893 OR p2.proargtypes[0] != 'internal'::regtype);
1894 oid | amname | oid | proname
1895 -----+--------+-----+---------
1898 -- **************** pg_amop ****************
1899 -- Look for illegal values in pg_amop fields
1900 SELECT p1.amopfamily, p1.amopstrategy
1902 WHERE p1.amopfamily = 0 OR p1.amoplefttype = 0 OR p1.amoprighttype = 0
1903 OR p1.amopopr = 0 OR p1.amopmethod = 0 OR p1.amopstrategy < 1;
1904 amopfamily | amopstrategy
1905 ------------+--------------
1908 SELECT p1.amopfamily, p1.amopstrategy
1910 WHERE NOT ((p1.amoppurpose = 's' AND p1.amopsortfamily = 0) OR
1911 (p1.amoppurpose = 'o' AND p1.amopsortfamily <> 0));
1912 amopfamily | amopstrategy
1913 ------------+--------------
1916 -- amopmethod must match owning opfamily's opfmethod
1917 SELECT p1.oid, p2.oid
1918 FROM pg_amop AS p1, pg_opfamily AS p2
1919 WHERE p1.amopfamily = p2.oid AND p1.amopmethod != p2.opfmethod;
1924 -- Make a list of all the distinct operator names being used in particular
1925 -- strategy slots. This is a bit hokey, since the list might need to change
1926 -- in future releases, but it's an effective way of spotting mistakes such as
1927 -- swapping two operators within a family.
1928 SELECT DISTINCT amopmethod, amopstrategy, oprname
1929 FROM pg_amop p1 LEFT JOIN pg_operator p2 ON amopopr = p2.oid
1931 amopmethod | amopstrategy | oprname
1932 ------------+--------------+---------
2059 -- Check that all opclass search operators have selectivity estimators.
2060 -- This is not absolutely required, but it seems a reasonable thing
2061 -- to insist on for all standard datatypes.
2062 SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname
2063 FROM pg_amop AS p1, pg_operator AS p2
2064 WHERE p1.amopopr = p2.oid AND p1.amoppurpose = 's' AND
2065 (p2.oprrest = 0 OR p2.oprjoin = 0);
2066 amopfamily | amopopr | oid | oprname
2067 ------------+---------+-----+---------
2070 -- Check that each opclass in an opfamily has associated operators, that is
2071 -- ones whose oprleft matches opcintype (possibly by coercion).
2072 SELECT p1.opcname, p1.opcfamily
2073 FROM pg_opclass AS p1
2074 WHERE NOT EXISTS(SELECT 1 FROM pg_amop AS p2
2075 WHERE p2.amopfamily = p1.opcfamily
2076 AND binary_coercible(p1.opcintype, p2.amoplefttype));
2078 ---------+-----------
2081 -- Check that each operator listed in pg_amop has an associated opclass,
2082 -- that is one whose opcintype matches oprleft (possibly by coercion).
2083 -- Otherwise the operator is useless because it cannot be matched to an index.
2084 -- (In principle it could be useful to list such operators in multiple-datatype
2085 -- btree opfamilies, but in practice you'd expect there to be an opclass for
2086 -- every datatype the family knows about.)
2087 SELECT p1.amopfamily, p1.amopstrategy, p1.amopopr
2089 WHERE NOT EXISTS(SELECT 1 FROM pg_opclass AS p2
2090 WHERE p2.opcfamily = p1.amopfamily
2091 AND binary_coercible(p2.opcintype, p1.amoplefttype));
2092 amopfamily | amopstrategy | amopopr
2093 ------------+--------------+---------
2096 -- Operators that are primary members of opclasses must be immutable (else
2097 -- it suggests that the index ordering isn't fixed). Operators that are
2098 -- cross-type members need only be stable, since they are just shorthands
2099 -- for index probe queries.
2100 SELECT p1.amopfamily, p1.amopopr, p2.oprname, p3.prosrc
2101 FROM pg_amop AS p1, pg_operator AS p2, pg_proc AS p3
2102 WHERE p1.amopopr = p2.oid AND p2.oprcode = p3.oid AND
2103 p1.amoplefttype = p1.amoprighttype AND
2104 p3.provolatile != 'i';
2105 amopfamily | amopopr | oprname | prosrc
2106 ------------+---------+---------+--------
2109 SELECT p1.amopfamily, p1.amopopr, p2.oprname, p3.prosrc
2110 FROM pg_amop AS p1, pg_operator AS p2, pg_proc AS p3
2111 WHERE p1.amopopr = p2.oid AND p2.oprcode = p3.oid AND
2112 p1.amoplefttype != p1.amoprighttype AND
2113 p3.provolatile = 'v';
2114 amopfamily | amopopr | oprname | prosrc
2115 ------------+---------+---------+--------
2118 -- **************** pg_amproc ****************
2119 -- Look for illegal values in pg_amproc fields
2120 SELECT p1.amprocfamily, p1.amprocnum
2121 FROM pg_amproc as p1
2122 WHERE p1.amprocfamily = 0 OR p1.amproclefttype = 0 OR p1.amprocrighttype = 0
2123 OR p1.amprocnum < 0 OR p1.amproc = 0;
2124 amprocfamily | amprocnum
2125 --------------+-----------
2128 -- Support routines that are primary members of opfamilies must be immutable
2129 -- (else it suggests that the index ordering isn't fixed). But cross-type
2130 -- members need only be stable, since they are just shorthands
2131 -- for index probe queries.
2132 SELECT p1.amprocfamily, p1.amproc, p2.prosrc
2133 FROM pg_amproc AS p1, pg_proc AS p2
2134 WHERE p1.amproc = p2.oid AND
2135 p1.amproclefttype = p1.amprocrighttype AND
2136 p2.provolatile != 'i';
2137 amprocfamily | amproc | prosrc
2138 --------------+--------+--------
2141 SELECT p1.amprocfamily, p1.amproc, p2.prosrc
2142 FROM pg_amproc AS p1, pg_proc AS p2
2143 WHERE p1.amproc = p2.oid AND
2144 p1.amproclefttype != p1.amprocrighttype AND
2145 p2.provolatile = 'v';
2146 amprocfamily | amproc | prosrc
2147 --------------+--------+--------
2150 -- Almost all of the core distribution's Btree opclasses can use one of the
2151 -- two generic "equalimage" functions as their support function 4. Look for
2152 -- opclasses that don't allow deduplication unconditionally here.
2154 -- Newly added Btree opclasses don't have to support deduplication. It will
2155 -- usually be trivial to add support, though. Note that the expected output
2156 -- of this part of the test will need to be updated when a new opclass cannot
2157 -- support deduplication (by using btequalimage).
2158 SELECT amp.amproc::regproc AS proc, opf.opfname AS opfamily_name,
2159 opc.opcname AS opclass_name, opc.opcintype::regtype AS opcintype
2161 JOIN pg_opclass AS opc ON opc.opcmethod = am.oid
2162 JOIN pg_opfamily AS opf ON opc.opcfamily = opf.oid
2163 LEFT JOIN pg_amproc AS amp ON amp.amprocfamily = opf.oid AND
2164 amp.amproclefttype = opc.opcintype AND amp.amprocnum = 4
2165 WHERE am.amname = 'btree' AND
2166 amp.amproc IS DISTINCT FROM 'btequalimage'::regproc
2168 proc | opfamily_name | opclass_name | opcintype
2169 --------------------+------------------+------------------+------------------
2170 btvarstrequalimage | bpchar_ops | bpchar_ops | character
2171 btvarstrequalimage | text_ops | name_ops | name
2172 btvarstrequalimage | text_ops | text_ops | text
2173 btvarstrequalimage | text_ops | varchar_ops | text
2174 | array_ops | array_ops | anyarray
2175 | float_ops | float4_ops | real
2176 | float_ops | float8_ops | double precision
2177 | jsonb_ops | jsonb_ops | jsonb
2178 | multirange_ops | multirange_ops | anymultirange
2179 | numeric_ops | numeric_ops | numeric
2180 | range_ops | range_ops | anyrange
2181 | record_image_ops | record_image_ops | record
2182 | record_ops | record_ops | record
2183 | tsquery_ops | tsquery_ops | tsquery
2184 | tsvector_ops | tsvector_ops | tsvector
2187 -- **************** pg_index ****************
2188 -- Look for illegal values in pg_index fields.
2189 SELECT p1.indexrelid, p1.indrelid
2191 WHERE p1.indexrelid = 0 OR p1.indrelid = 0 OR
2192 p1.indnatts <= 0 OR p1.indnatts > 32;
2193 indexrelid | indrelid
2194 ------------+----------
2197 -- oidvector and int2vector fields should be of length indnatts.
2198 SELECT p1.indexrelid, p1.indrelid
2200 WHERE array_lower(indkey, 1) != 0 OR array_upper(indkey, 1) != indnatts-1 OR
2201 array_lower(indclass, 1) != 0 OR array_upper(indclass, 1) != indnatts-1 OR
2202 array_lower(indcollation, 1) != 0 OR array_upper(indcollation, 1) != indnatts-1 OR
2203 array_lower(indoption, 1) != 0 OR array_upper(indoption, 1) != indnatts-1;
2204 indexrelid | indrelid
2205 ------------+----------
2208 -- Check that opclasses and collations match the underlying columns.
2209 -- (As written, this test ignores expression indexes.)
2210 SELECT indexrelid::regclass, indrelid::regclass, attname, atttypid::regtype, opcname
2211 FROM (SELECT indexrelid, indrelid, unnest(indkey) as ikey,
2212 unnest(indclass) as iclass, unnest(indcollation) as icoll
2216 WHERE a.attrelid = indrelid AND a.attnum = ikey AND opc.oid = iclass AND
2217 (NOT binary_coercible(atttypid, opcintype) OR icoll != attcollation);
2218 indexrelid | indrelid | attname | atttypid | opcname
2219 ------------+----------+---------+----------+---------
2222 -- For system catalogs, be even tighter: nearly all indexes should be
2223 -- exact type matches not binary-coercible matches. At this writing
2224 -- the only exception is an OID index on a regproc column.
2225 SELECT indexrelid::regclass, indrelid::regclass, attname, atttypid::regtype, opcname
2226 FROM (SELECT indexrelid, indrelid, unnest(indkey) as ikey,
2227 unnest(indclass) as iclass, unnest(indcollation) as icoll
2229 WHERE indrelid < 16384) ss,
2232 WHERE a.attrelid = indrelid AND a.attnum = ikey AND opc.oid = iclass AND
2233 (opcintype != atttypid OR icoll != attcollation)
2235 indexrelid | indrelid | attname | atttypid | opcname
2236 --------------------------+--------------+----------+----------+---------
2237 pg_aggregate_fnoid_index | pg_aggregate | aggfnoid | regproc | oid_ops
2240 -- Check for system catalogs with collation-sensitive ordering. This is not
2241 -- a representational error in pg_index, but simply wrong catalog design.
2242 -- It's bad because we expect to be able to clone template0 and assign the
2243 -- copy a different database collation. It would especially not work for
2245 SELECT relname, attname, attcollation
2246 FROM pg_class c, pg_attribute a
2247 WHERE c.oid = attrelid AND c.oid < 16384 AND
2248 c.relkind != 'v' AND -- we don't care about columns in views
2249 attcollation != 0 AND
2250 attcollation != (SELECT oid FROM pg_collation WHERE collname = 'C');
2251 relname | attname | attcollation
2252 ---------+---------+--------------
2255 -- Double-check that collation-sensitive indexes have "C" collation, too.
2256 SELECT indexrelid::regclass, indrelid::regclass, iclass, icoll
2257 FROM (SELECT indexrelid, indrelid,
2258 unnest(indclass) as iclass, unnest(indcollation) as icoll
2260 WHERE indrelid < 16384) ss
2261 WHERE icoll != 0 AND
2262 icoll != (SELECT oid FROM pg_collation WHERE collname = 'C');
2263 indexrelid | indrelid | iclass | icoll
2264 ------------+----------+--------+-------