Improve correlation names in sanity tests

Some of the queries in the "sanity" tests in the regression test suite
(opr_sanity, type_sanity) are very confusing.  One main stumbling
block is that for some probably ancient reason many of the older
queries are written with correlation names p1, p2, etc. independent of
the name of the catalog. This one is a good example:

SELECT p1.oid, p1.oprname, p2.oid, p2.proname
FROM pg_operator AS p1, pg_proc AS p2          <-- HERE
WHERE p1.oprcode = p2.oid AND
    p1.oprkind = 'l' AND
    (p2.pronargs != 1
     OR NOT binary_coercible(p2.prorettype, p1.oprresult)
     OR NOT binary_coercible(p1.oprright, p2.proargtypes[0])
     OR p1.oprleft != 0);

This is better written as

SELECT o1.oid, o1.oprname, p1.oid, p1.proname
FROM pg_operator AS o1, pg_proc AS p1
WHERE o1.oprcode = p1.oid AND
    o1.oprkind = 'l' AND
    (p1.pronargs != 1
     OR NOT binary_coercible(p1.prorettype, o1.oprresult)
     OR NOT binary_coercible(o1.oprright, p1.proargtypes[0])
     OR o1.oprleft != 0);

This patch cleans up all the queries in this manner.

(As in the above case, I kept the digits like o1 and p1 even in cases
where only one of each letter is used in a query.  This is mainly to
keep the style consistent.)

Discussion: https://www.postgresql.org/message-id/flat/c538308b-319c-8784-e250-1284d12d5411%40enterprisedb.com
This commit is contained in:
Peter Eisentraut 2022-02-13 21:07:25 +01:00
parent cba5b994c9
commit 9898c5e03c
4 changed files with 840 additions and 840 deletions

View File

@ -991,9 +991,9 @@ WHERE c.castmethod = 'b' AND
-- **************** pg_conversion **************** -- **************** pg_conversion ****************
-- Look for illegal values in pg_conversion fields. -- Look for illegal values in pg_conversion fields.
SELECT p1.oid, p1.conname SELECT c.oid, c.conname
FROM pg_conversion as p1 FROM pg_conversion as c
WHERE p1.conproc = 0 OR WHERE c.conproc = 0 OR
pg_encoding_to_char(conforencoding) = '' OR pg_encoding_to_char(conforencoding) = '' OR
pg_encoding_to_char(contoencoding) = ''; pg_encoding_to_char(contoencoding) = '';
oid | conname oid | conname
@ -1025,8 +1025,8 @@ WHERE p.oid = c.conproc AND
-- them directly from SQL. But there are no non-default built-in -- them directly from SQL. But there are no non-default built-in
-- conversions anyway. -- conversions anyway.
-- (Similarly, this doesn't cope with any search path issues.) -- (Similarly, this doesn't cope with any search path issues.)
SELECT p1.oid, p1.conname SELECT c.oid, c.conname
FROM pg_conversion as p1 FROM pg_conversion as c
WHERE condefault AND WHERE condefault AND
convert('ABC'::bytea, pg_encoding_to_char(conforencoding), convert('ABC'::bytea, pg_encoding_to_char(conforencoding),
pg_encoding_to_char(contoencoding)) != 'ABC'; pg_encoding_to_char(contoencoding)) != 'ABC';
@ -1036,32 +1036,32 @@ WHERE condefault AND
-- **************** pg_operator **************** -- **************** pg_operator ****************
-- Look for illegal values in pg_operator fields. -- Look for illegal values in pg_operator fields.
SELECT p1.oid, p1.oprname SELECT o1.oid, o1.oprname
FROM pg_operator as p1 FROM pg_operator as o1
WHERE (p1.oprkind != 'b' AND p1.oprkind != 'l') OR WHERE (o1.oprkind != 'b' AND o1.oprkind != 'l') OR
p1.oprresult = 0 OR p1.oprcode = 0; o1.oprresult = 0 OR o1.oprcode = 0;
oid | oprname oid | oprname
-----+--------- -----+---------
(0 rows) (0 rows)
-- Look for missing or unwanted operand types -- Look for missing or unwanted operand types
SELECT p1.oid, p1.oprname SELECT o1.oid, o1.oprname
FROM pg_operator as p1 FROM pg_operator as o1
WHERE (p1.oprleft = 0 and p1.oprkind != 'l') OR WHERE (o1.oprleft = 0 and o1.oprkind != 'l') OR
(p1.oprleft != 0 and p1.oprkind = 'l') OR (o1.oprleft != 0 and o1.oprkind = 'l') OR
p1.oprright = 0; o1.oprright = 0;
oid | oprname oid | oprname
-----+--------- -----+---------
(0 rows) (0 rows)
-- Look for conflicting operator definitions (same names and input datatypes). -- Look for conflicting operator definitions (same names and input datatypes).
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode
FROM pg_operator AS p1, pg_operator AS p2 FROM pg_operator AS o1, pg_operator AS o2
WHERE p1.oid != p2.oid AND WHERE o1.oid != o2.oid AND
p1.oprname = p2.oprname AND o1.oprname = o2.oprname AND
p1.oprkind = p2.oprkind AND o1.oprkind = o2.oprkind AND
p1.oprleft = p2.oprleft AND o1.oprleft = o2.oprleft AND
p1.oprright = p2.oprright; o1.oprright = o2.oprright;
oid | oprcode | oid | oprcode oid | oprcode | oid | oprcode
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
@ -1070,14 +1070,14 @@ WHERE p1.oid != p2.oid AND
-- DEFINITIONAL NOTE: If A.oprcom = B, then x A y has the same result as y B x. -- DEFINITIONAL NOTE: If A.oprcom = B, then x A y has the same result as y B x.
-- We expect that B will always say that B.oprcom = A as well; that's not -- We expect that B will always say that B.oprcom = A as well; that's not
-- inherently essential, but it would be inefficient not to mark it so. -- inherently essential, but it would be inefficient not to mark it so.
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode
FROM pg_operator AS p1, pg_operator AS p2 FROM pg_operator AS o1, pg_operator AS o2
WHERE p1.oprcom = p2.oid AND WHERE o1.oprcom = o2.oid AND
(p1.oprkind != 'b' OR (o1.oprkind != 'b' OR
p1.oprleft != p2.oprright OR o1.oprleft != o2.oprright OR
p1.oprright != p2.oprleft OR o1.oprright != o2.oprleft OR
p1.oprresult != p2.oprresult OR o1.oprresult != o2.oprresult OR
p1.oid != p2.oprcom); o1.oid != o2.oprcom);
oid | oprcode | oid | oprcode oid | oprcode | oid | oprcode
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
@ -1089,16 +1089,16 @@ WHERE p1.oprcom = p2.oid AND
-- We expect that B will always say that B.oprnegate = A as well; that's not -- We expect that B will always say that B.oprnegate = A as well; that's not
-- inherently essential, but it would be inefficient not to mark it so. -- inherently essential, but it would be inefficient not to mark it so.
-- Also, A and B had better not be the same operator. -- Also, A and B had better not be the same operator.
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode
FROM pg_operator AS p1, pg_operator AS p2 FROM pg_operator AS o1, pg_operator AS o2
WHERE p1.oprnegate = p2.oid AND WHERE o1.oprnegate = o2.oid AND
(p1.oprkind != p2.oprkind OR (o1.oprkind != o2.oprkind OR
p1.oprleft != p2.oprleft OR o1.oprleft != o2.oprleft OR
p1.oprright != p2.oprright OR o1.oprright != o2.oprright OR
p1.oprresult != 'bool'::regtype OR o1.oprresult != 'bool'::regtype OR
p2.oprresult != 'bool'::regtype OR o2.oprresult != 'bool'::regtype OR
p1.oid != p2.oprnegate OR o1.oid != o2.oprnegate OR
p1.oid = p2.oid); o1.oid = o2.oid);
oid | oprcode | oid | oprcode oid | oprcode | oid | oprcode
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
@ -1168,100 +1168,100 @@ ORDER BY 1, 2;
-- A mergejoinable or hashjoinable operator must be binary, must return -- A mergejoinable or hashjoinable operator must be binary, must return
-- boolean, and must have a commutator (itself, unless it's a cross-type -- boolean, and must have a commutator (itself, unless it's a cross-type
-- operator). -- operator).
SELECT p1.oid, p1.oprname FROM pg_operator AS p1 SELECT o1.oid, o1.oprname FROM pg_operator AS o1
WHERE (p1.oprcanmerge OR p1.oprcanhash) AND NOT WHERE (o1.oprcanmerge OR o1.oprcanhash) AND NOT
(p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND p1.oprcom != 0); (o1.oprkind = 'b' AND o1.oprresult = 'bool'::regtype AND o1.oprcom != 0);
oid | oprname oid | oprname
-----+--------- -----+---------
(0 rows) (0 rows)
-- What's more, the commutator had better be mergejoinable/hashjoinable too. -- What's more, the commutator had better be mergejoinable/hashjoinable too.
SELECT p1.oid, p1.oprname, p2.oid, p2.oprname SELECT o1.oid, o1.oprname, o2.oid, o2.oprname
FROM pg_operator AS p1, pg_operator AS p2 FROM pg_operator AS o1, pg_operator AS o2
WHERE p1.oprcom = p2.oid AND WHERE o1.oprcom = o2.oid AND
(p1.oprcanmerge != p2.oprcanmerge OR (o1.oprcanmerge != o2.oprcanmerge OR
p1.oprcanhash != p2.oprcanhash); o1.oprcanhash != o2.oprcanhash);
oid | oprname | oid | oprname oid | oprname | oid | oprname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- Mergejoinable operators should appear as equality members of btree index -- Mergejoinable operators should appear as equality members of btree index
-- opfamilies. -- opfamilies.
SELECT p1.oid, p1.oprname SELECT o1.oid, o1.oprname
FROM pg_operator AS p1 FROM pg_operator AS o1
WHERE p1.oprcanmerge AND NOT EXISTS WHERE o1.oprcanmerge AND NOT EXISTS
(SELECT 1 FROM pg_amop (SELECT 1 FROM pg_amop
WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND
amopopr = p1.oid AND amopstrategy = 3); amopopr = o1.oid AND amopstrategy = 3);
oid | oprname oid | oprname
-----+--------- -----+---------
(0 rows) (0 rows)
-- And the converse. -- And the converse.
SELECT p1.oid, p1.oprname, p.amopfamily SELECT o1.oid, o1.oprname, p.amopfamily
FROM pg_operator AS p1, pg_amop p FROM pg_operator AS o1, pg_amop p
WHERE amopopr = p1.oid WHERE amopopr = o1.oid
AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree')
AND amopstrategy = 3 AND amopstrategy = 3
AND NOT p1.oprcanmerge; AND NOT o1.oprcanmerge;
oid | oprname | amopfamily oid | oprname | amopfamily
-----+---------+------------ -----+---------+------------
(0 rows) (0 rows)
-- Hashable operators should appear as members of hash index opfamilies. -- Hashable operators should appear as members of hash index opfamilies.
SELECT p1.oid, p1.oprname SELECT o1.oid, o1.oprname
FROM pg_operator AS p1 FROM pg_operator AS o1
WHERE p1.oprcanhash AND NOT EXISTS WHERE o1.oprcanhash AND NOT EXISTS
(SELECT 1 FROM pg_amop (SELECT 1 FROM pg_amop
WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND
amopopr = p1.oid AND amopstrategy = 1); amopopr = o1.oid AND amopstrategy = 1);
oid | oprname oid | oprname
-----+--------- -----+---------
(0 rows) (0 rows)
-- And the converse. -- And the converse.
SELECT p1.oid, p1.oprname, p.amopfamily SELECT o1.oid, o1.oprname, p.amopfamily
FROM pg_operator AS p1, pg_amop p FROM pg_operator AS o1, pg_amop p
WHERE amopopr = p1.oid WHERE amopopr = o1.oid
AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash')
AND NOT p1.oprcanhash; AND NOT o1.oprcanhash;
oid | oprname | amopfamily oid | oprname | amopfamily
-----+---------+------------ -----+---------+------------
(0 rows) (0 rows)
-- Check that each operator defined in pg_operator matches its oprcode entry -- Check that each operator defined in pg_operator matches its oprcode entry
-- in pg_proc. Easiest to do this separately for each oprkind. -- in pg_proc. Easiest to do this separately for each oprkind.
SELECT p1.oid, p1.oprname, p2.oid, p2.proname SELECT o1.oid, o1.oprname, p1.oid, p1.proname
FROM pg_operator AS p1, pg_proc AS p2 FROM pg_operator AS o1, pg_proc AS p1
WHERE p1.oprcode = p2.oid AND WHERE o1.oprcode = p1.oid AND
p1.oprkind = 'b' AND o1.oprkind = 'b' AND
(p2.pronargs != 2 (p1.pronargs != 2
OR NOT binary_coercible(p2.prorettype, p1.oprresult) OR NOT binary_coercible(p1.prorettype, o1.oprresult)
OR NOT binary_coercible(p1.oprleft, p2.proargtypes[0]) OR NOT binary_coercible(o1.oprleft, p1.proargtypes[0])
OR NOT binary_coercible(p1.oprright, p2.proargtypes[1])); OR NOT binary_coercible(o1.oprright, p1.proargtypes[1]));
oid | oprname | oid | proname oid | oprname | oid | proname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
SELECT p1.oid, p1.oprname, p2.oid, p2.proname SELECT o1.oid, o1.oprname, p1.oid, p1.proname
FROM pg_operator AS p1, pg_proc AS p2 FROM pg_operator AS o1, pg_proc AS p1
WHERE p1.oprcode = p2.oid AND WHERE o1.oprcode = p1.oid AND
p1.oprkind = 'l' AND o1.oprkind = 'l' AND
(p2.pronargs != 1 (p1.pronargs != 1
OR NOT binary_coercible(p2.prorettype, p1.oprresult) OR NOT binary_coercible(p1.prorettype, o1.oprresult)
OR NOT binary_coercible(p1.oprright, p2.proargtypes[0]) OR NOT binary_coercible(o1.oprright, p1.proargtypes[0])
OR p1.oprleft != 0); OR o1.oprleft != 0);
oid | oprname | oid | proname oid | oprname | oid | proname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- If the operator is mergejoinable or hashjoinable, its underlying function -- If the operator is mergejoinable or hashjoinable, its underlying function
-- should not be volatile. -- should not be volatile.
SELECT p1.oid, p1.oprname, p2.oid, p2.proname SELECT o1.oid, o1.oprname, p1.oid, p1.proname
FROM pg_operator AS p1, pg_proc AS p2 FROM pg_operator AS o1, pg_proc AS p1
WHERE p1.oprcode = p2.oid AND WHERE o1.oprcode = p1.oid AND
(p1.oprcanmerge OR p1.oprcanhash) AND (o1.oprcanmerge OR o1.oprcanhash) AND
p2.provolatile = 'v'; p1.provolatile = 'v';
oid | oprname | oid | proname oid | oprname | oid | proname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
@ -1270,10 +1270,10 @@ WHERE p1.oprcode = p2.oid AND
-- and it must link to a proc with the right signature -- and it must link to a proc with the right signature
-- to be a restriction selectivity estimator. -- to be a restriction selectivity estimator.
-- The proc signature we want is: float8 proc(internal, oid, internal, int4) -- The proc signature we want is: float8 proc(internal, oid, internal, int4)
SELECT p1.oid, p1.oprname, p2.oid, p2.proname SELECT o1.oid, o1.oprname, p2.oid, p2.proname
FROM pg_operator AS p1, pg_proc AS p2 FROM pg_operator AS o1, pg_proc AS p2
WHERE p1.oprrest = p2.oid AND WHERE o1.oprrest = p2.oid AND
(p1.oprresult != 'bool'::regtype OR (o1.oprresult != 'bool'::regtype OR
p2.prorettype != 'float8'::regtype OR p2.proretset OR p2.prorettype != 'float8'::regtype OR p2.proretset OR
p2.pronargs != 4 OR p2.pronargs != 4 OR
p2.proargtypes[0] != 'internal'::regtype OR p2.proargtypes[0] != 'internal'::regtype OR
@ -1290,10 +1290,10 @@ WHERE p1.oprrest = p2.oid AND
-- The proc signature we want is: float8 proc(internal, oid, internal, int2, internal) -- The proc signature we want is: float8 proc(internal, oid, internal, int2, internal)
-- (Note: the old signature with only 4 args is still allowed, but no core -- (Note: the old signature with only 4 args is still allowed, but no core
-- estimator should be using it.) -- estimator should be using it.)
SELECT p1.oid, p1.oprname, p2.oid, p2.proname SELECT o1.oid, o1.oprname, p2.oid, p2.proname
FROM pg_operator AS p1, pg_proc AS p2 FROM pg_operator AS o1, pg_proc AS p2
WHERE p1.oprjoin = p2.oid AND WHERE o1.oprjoin = p2.oid AND
(p1.oprkind != 'b' OR p1.oprresult != 'bool'::regtype OR (o1.oprkind != 'b' OR o1.oprresult != 'bool'::regtype OR
p2.prorettype != 'float8'::regtype OR p2.proretset OR p2.prorettype != 'float8'::regtype OR p2.proretset OR
p2.pronargs != 5 OR p2.pronargs != 5 OR
p2.proargtypes[0] != 'internal'::regtype OR p2.proargtypes[0] != 'internal'::regtype OR
@ -1306,10 +1306,10 @@ WHERE p1.oprjoin = p2.oid AND
(0 rows) (0 rows)
-- Insist that all built-in pg_operator entries have descriptions -- Insist that all built-in pg_operator entries have descriptions
SELECT p1.oid, p1.oprname SELECT o1.oid, o1.oprname
FROM pg_operator as p1 LEFT JOIN pg_description as d FROM pg_operator as o1 LEFT JOIN pg_description as d
ON p1.tableoid = d.classoid and p1.oid = d.objoid and d.objsubid = 0 ON o1.tableoid = d.classoid and o1.oid = d.objoid and d.objsubid = 0
WHERE d.classoid IS NULL AND p1.oid <= 9999; WHERE d.classoid IS NULL AND o1.oid <= 9999;
oid | oprname oid | oprname
-----+--------- -----+---------
(0 rows) (0 rows)
@ -1417,7 +1417,7 @@ ORDER BY 1;
-- **************** pg_aggregate **************** -- **************** pg_aggregate ****************
-- Look for illegal values in pg_aggregate fields. -- Look for illegal values in pg_aggregate fields.
SELECT ctid, aggfnoid::oid SELECT ctid, aggfnoid::oid
FROM pg_aggregate as p1 FROM pg_aggregate as a
WHERE aggfnoid = 0 OR aggtransfn = 0 OR WHERE aggfnoid = 0 OR aggtransfn = 0 OR
aggkind NOT IN ('n', 'o', 'h') OR aggkind NOT IN ('n', 'o', 'h') OR
aggnumdirectargs < 0 OR aggnumdirectargs < 0 OR
@ -1518,7 +1518,7 @@ WHERE a.aggfnoid = p.oid AND
-- Check for inconsistent specifications of moving-aggregate columns. -- Check for inconsistent specifications of moving-aggregate columns.
SELECT ctid, aggfnoid::oid SELECT ctid, aggfnoid::oid
FROM pg_aggregate as p1 FROM pg_aggregate as a
WHERE aggmtranstype != 0 AND WHERE aggmtranstype != 0 AND
(aggmtransfn = 0 OR aggminvtransfn = 0); (aggmtransfn = 0 OR aggminvtransfn = 0);
ctid | aggfnoid ctid | aggfnoid
@ -1526,7 +1526,7 @@ WHERE aggmtranstype != 0 AND
(0 rows) (0 rows)
SELECT ctid, aggfnoid::oid SELECT ctid, aggfnoid::oid
FROM pg_aggregate as p1 FROM pg_aggregate as a
WHERE aggmtranstype = 0 AND WHERE aggmtranstype = 0 AND
(aggmtransfn != 0 OR aggminvtransfn != 0 OR aggmfinalfn != 0 OR (aggmtransfn != 0 OR aggminvtransfn != 0 OR aggmfinalfn != 0 OR
aggmtransspace != 0 OR aggminitval IS NOT NULL); aggmtransspace != 0 OR aggminitval IS NOT NULL);
@ -1809,9 +1809,9 @@ WHERE prokind = 'a' AND provariadic != 0 AND a.aggkind = 'n';
-- **************** pg_opfamily **************** -- **************** pg_opfamily ****************
-- Look for illegal values in pg_opfamily fields -- Look for illegal values in pg_opfamily fields
SELECT p1.oid SELECT f.oid
FROM pg_opfamily as p1 FROM pg_opfamily as f
WHERE p1.opfmethod = 0 OR p1.opfnamespace = 0; WHERE f.opfmethod = 0 OR f.opfnamespace = 0;
oid oid
----- -----
(0 rows) (0 rows)
@ -1828,29 +1828,29 @@ WHERE NOT EXISTS (SELECT 1 FROM pg_opclass WHERE opcfamily = f.oid);
-- **************** pg_opclass **************** -- **************** pg_opclass ****************
-- Look for illegal values in pg_opclass fields -- Look for illegal values in pg_opclass fields
SELECT p1.oid SELECT c1.oid
FROM pg_opclass AS p1 FROM pg_opclass AS c1
WHERE p1.opcmethod = 0 OR p1.opcnamespace = 0 OR p1.opcfamily = 0 WHERE c1.opcmethod = 0 OR c1.opcnamespace = 0 OR c1.opcfamily = 0
OR p1.opcintype = 0; OR c1.opcintype = 0;
oid oid
----- -----
(0 rows) (0 rows)
-- opcmethod must match owning opfamily's opfmethod -- opcmethod must match owning opfamily's opfmethod
SELECT p1.oid, p2.oid SELECT c1.oid, f1.oid
FROM pg_opclass AS p1, pg_opfamily AS p2 FROM pg_opclass AS c1, pg_opfamily AS f1
WHERE p1.opcfamily = p2.oid AND p1.opcmethod != p2.opfmethod; WHERE c1.opcfamily = f1.oid AND c1.opcmethod != f1.opfmethod;
oid | oid oid | oid
-----+----- -----+-----
(0 rows) (0 rows)
-- There should not be multiple entries in pg_opclass with opcdefault true -- There should not be multiple entries in pg_opclass with opcdefault true
-- and the same opcmethod/opcintype combination. -- and the same opcmethod/opcintype combination.
SELECT p1.oid, p2.oid SELECT c1.oid, c2.oid
FROM pg_opclass AS p1, pg_opclass AS p2 FROM pg_opclass AS c1, pg_opclass AS c2
WHERE p1.oid != p2.oid AND WHERE c1.oid != c2.oid AND
p1.opcmethod = p2.opcmethod AND p1.opcintype = p2.opcintype AND c1.opcmethod = c2.opcmethod AND c1.opcintype = c2.opcintype AND
p1.opcdefault AND p2.opcdefault; c1.opcdefault AND c2.opcdefault;
oid | oid oid | oid
-----+----- -----+-----
(0 rows) (0 rows)
@ -1864,59 +1864,59 @@ SELECT oid, opcname FROM pg_opclass WHERE NOT amvalidate(oid);
-- **************** pg_am **************** -- **************** pg_am ****************
-- Look for illegal values in pg_am fields -- Look for illegal values in pg_am fields
SELECT p1.oid, p1.amname SELECT a1.oid, a1.amname
FROM pg_am AS p1 FROM pg_am AS a1
WHERE p1.amhandler = 0; WHERE a1.amhandler = 0;
oid | amname oid | amname
-----+-------- -----+--------
(0 rows) (0 rows)
-- Check for index amhandler functions with the wrong signature -- Check for index amhandler functions with the wrong signature
SELECT p1.oid, p1.amname, p2.oid, p2.proname SELECT a1.oid, a1.amname, p1.oid, p1.proname
FROM pg_am AS p1, pg_proc AS p2 FROM pg_am AS a1, pg_proc AS p1
WHERE p2.oid = p1.amhandler AND p1.amtype = 'i' AND WHERE p1.oid = a1.amhandler AND a1.amtype = 'i' AND
(p2.prorettype != 'index_am_handler'::regtype (p1.prorettype != 'index_am_handler'::regtype
OR p2.proretset OR p1.proretset
OR p2.pronargs != 1 OR p1.pronargs != 1
OR p2.proargtypes[0] != 'internal'::regtype); OR p1.proargtypes[0] != 'internal'::regtype);
oid | amname | oid | proname oid | amname | oid | proname
-----+--------+-----+--------- -----+--------+-----+---------
(0 rows) (0 rows)
-- Check for table amhandler functions with the wrong signature -- Check for table amhandler functions with the wrong signature
SELECT p1.oid, p1.amname, p2.oid, p2.proname SELECT a1.oid, a1.amname, p1.oid, p1.proname
FROM pg_am AS p1, pg_proc AS p2 FROM pg_am AS a1, pg_proc AS p1
WHERE p2.oid = p1.amhandler AND p1.amtype = 's' AND WHERE p1.oid = a1.amhandler AND a1.amtype = 's' AND
(p2.prorettype != 'table_am_handler'::regtype (p1.prorettype != 'table_am_handler'::regtype
OR p2.proretset OR p1.proretset
OR p2.pronargs != 1 OR p1.pronargs != 1
OR p2.proargtypes[0] != 'internal'::regtype); OR p1.proargtypes[0] != 'internal'::regtype);
oid | amname | oid | proname oid | amname | oid | proname
-----+--------+-----+--------- -----+--------+-----+---------
(0 rows) (0 rows)
-- **************** pg_amop **************** -- **************** pg_amop ****************
-- Look for illegal values in pg_amop fields -- Look for illegal values in pg_amop fields
SELECT p1.amopfamily, p1.amopstrategy SELECT a1.amopfamily, a1.amopstrategy
FROM pg_amop as p1 FROM pg_amop as a1
WHERE p1.amopfamily = 0 OR p1.amoplefttype = 0 OR p1.amoprighttype = 0 WHERE a1.amopfamily = 0 OR a1.amoplefttype = 0 OR a1.amoprighttype = 0
OR p1.amopopr = 0 OR p1.amopmethod = 0 OR p1.amopstrategy < 1; OR a1.amopopr = 0 OR a1.amopmethod = 0 OR a1.amopstrategy < 1;
amopfamily | amopstrategy amopfamily | amopstrategy
------------+-------------- ------------+--------------
(0 rows) (0 rows)
SELECT p1.amopfamily, p1.amopstrategy SELECT a1.amopfamily, a1.amopstrategy
FROM pg_amop as p1 FROM pg_amop as a1
WHERE NOT ((p1.amoppurpose = 's' AND p1.amopsortfamily = 0) OR WHERE NOT ((a1.amoppurpose = 's' AND a1.amopsortfamily = 0) OR
(p1.amoppurpose = 'o' AND p1.amopsortfamily <> 0)); (a1.amoppurpose = 'o' AND a1.amopsortfamily <> 0));
amopfamily | amopstrategy amopfamily | amopstrategy
------------+-------------- ------------+--------------
(0 rows) (0 rows)
-- amopmethod must match owning opfamily's opfmethod -- amopmethod must match owning opfamily's opfmethod
SELECT p1.oid, p2.oid SELECT a1.oid, f1.oid
FROM pg_amop AS p1, pg_opfamily AS p2 FROM pg_amop AS a1, pg_opfamily AS f1
WHERE p1.amopfamily = p2.oid AND p1.amopmethod != p2.opfmethod; WHERE a1.amopfamily = f1.oid AND a1.amopmethod != f1.opfmethod;
oid | oid oid | oid
-----+----- -----+-----
(0 rows) (0 rows)
@ -1926,7 +1926,7 @@ WHERE p1.amopfamily = p2.oid AND p1.amopmethod != p2.opfmethod;
-- in future releases, but it's an effective way of spotting mistakes such as -- in future releases, but it's an effective way of spotting mistakes such as
-- swapping two operators within a family. -- swapping two operators within a family.
SELECT DISTINCT amopmethod, amopstrategy, oprname SELECT DISTINCT amopmethod, amopstrategy, oprname
FROM pg_amop p1 LEFT JOIN pg_operator p2 ON amopopr = p2.oid FROM pg_amop a1 LEFT JOIN pg_operator o1 ON amopopr = o1.oid
ORDER BY 1, 2, 3; ORDER BY 1, 2, 3;
amopmethod | amopstrategy | oprname amopmethod | amopstrategy | oprname
------------+--------------+--------- ------------+--------------+---------
@ -2059,21 +2059,21 @@ ORDER BY 1, 2, 3;
-- Check that all opclass search operators have selectivity estimators. -- Check that all opclass search operators have selectivity estimators.
-- This is not absolutely required, but it seems a reasonable thing -- This is not absolutely required, but it seems a reasonable thing
-- to insist on for all standard datatypes. -- to insist on for all standard datatypes.
SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname SELECT a1.amopfamily, a1.amopopr, o1.oid, o1.oprname
FROM pg_amop AS p1, pg_operator AS p2 FROM pg_amop AS a1, pg_operator AS o1
WHERE p1.amopopr = p2.oid AND p1.amoppurpose = 's' AND WHERE a1.amopopr = o1.oid AND a1.amoppurpose = 's' AND
(p2.oprrest = 0 OR p2.oprjoin = 0); (o1.oprrest = 0 OR o1.oprjoin = 0);
amopfamily | amopopr | oid | oprname amopfamily | amopopr | oid | oprname
------------+---------+-----+--------- ------------+---------+-----+---------
(0 rows) (0 rows)
-- Check that each opclass in an opfamily has associated operators, that is -- Check that each opclass in an opfamily has associated operators, that is
-- ones whose oprleft matches opcintype (possibly by coercion). -- ones whose oprleft matches opcintype (possibly by coercion).
SELECT p1.opcname, p1.opcfamily SELECT c1.opcname, c1.opcfamily
FROM pg_opclass AS p1 FROM pg_opclass AS c1
WHERE NOT EXISTS(SELECT 1 FROM pg_amop AS p2 WHERE NOT EXISTS(SELECT 1 FROM pg_amop AS a1
WHERE p2.amopfamily = p1.opcfamily WHERE a1.amopfamily = c1.opcfamily
AND binary_coercible(p1.opcintype, p2.amoplefttype)); AND binary_coercible(c1.opcintype, a1.amoplefttype));
opcname | opcfamily opcname | opcfamily
---------+----------- ---------+-----------
(0 rows) (0 rows)
@ -2084,11 +2084,11 @@ WHERE NOT EXISTS(SELECT 1 FROM pg_amop AS p2
-- (In principle it could be useful to list such operators in multiple-datatype -- (In principle it could be useful to list such operators in multiple-datatype
-- btree opfamilies, but in practice you'd expect there to be an opclass for -- btree opfamilies, but in practice you'd expect there to be an opclass for
-- every datatype the family knows about.) -- every datatype the family knows about.)
SELECT p1.amopfamily, p1.amopstrategy, p1.amopopr SELECT a1.amopfamily, a1.amopstrategy, a1.amopopr
FROM pg_amop AS p1 FROM pg_amop AS a1
WHERE NOT EXISTS(SELECT 1 FROM pg_opclass AS p2 WHERE NOT EXISTS(SELECT 1 FROM pg_opclass AS c1
WHERE p2.opcfamily = p1.amopfamily WHERE c1.opcfamily = a1.amopfamily
AND binary_coercible(p2.opcintype, p1.amoplefttype)); AND binary_coercible(c1.opcintype, a1.amoplefttype));
amopfamily | amopstrategy | amopopr amopfamily | amopstrategy | amopopr
------------+--------------+--------- ------------+--------------+---------
(0 rows) (0 rows)
@ -2097,30 +2097,30 @@ WHERE NOT EXISTS(SELECT 1 FROM pg_opclass AS p2
-- it suggests that the index ordering isn't fixed). Operators that are -- it suggests that the index ordering isn't fixed). Operators that are
-- cross-type members need only be stable, since they are just shorthands -- cross-type members need only be stable, since they are just shorthands
-- for index probe queries. -- for index probe queries.
SELECT p1.amopfamily, p1.amopopr, p2.oprname, p3.prosrc SELECT a1.amopfamily, a1.amopopr, o1.oprname, p1.prosrc
FROM pg_amop AS p1, pg_operator AS p2, pg_proc AS p3 FROM pg_amop AS a1, pg_operator AS o1, pg_proc AS p1
WHERE p1.amopopr = p2.oid AND p2.oprcode = p3.oid AND WHERE a1.amopopr = o1.oid AND o1.oprcode = p1.oid AND
p1.amoplefttype = p1.amoprighttype AND a1.amoplefttype = a1.amoprighttype AND
p3.provolatile != 'i'; p1.provolatile != 'i';
amopfamily | amopopr | oprname | prosrc amopfamily | amopopr | oprname | prosrc
------------+---------+---------+-------- ------------+---------+---------+--------
(0 rows) (0 rows)
SELECT p1.amopfamily, p1.amopopr, p2.oprname, p3.prosrc SELECT a1.amopfamily, a1.amopopr, o1.oprname, p1.prosrc
FROM pg_amop AS p1, pg_operator AS p2, pg_proc AS p3 FROM pg_amop AS a1, pg_operator AS o1, pg_proc AS p1
WHERE p1.amopopr = p2.oid AND p2.oprcode = p3.oid AND WHERE a1.amopopr = o1.oid AND o1.oprcode = p1.oid AND
p1.amoplefttype != p1.amoprighttype AND a1.amoplefttype != a1.amoprighttype AND
p3.provolatile = 'v'; p1.provolatile = 'v';
amopfamily | amopopr | oprname | prosrc amopfamily | amopopr | oprname | prosrc
------------+---------+---------+-------- ------------+---------+---------+--------
(0 rows) (0 rows)
-- **************** pg_amproc **************** -- **************** pg_amproc ****************
-- Look for illegal values in pg_amproc fields -- Look for illegal values in pg_amproc fields
SELECT p1.amprocfamily, p1.amprocnum SELECT a1.amprocfamily, a1.amprocnum
FROM pg_amproc as p1 FROM pg_amproc as a1
WHERE p1.amprocfamily = 0 OR p1.amproclefttype = 0 OR p1.amprocrighttype = 0 WHERE a1.amprocfamily = 0 OR a1.amproclefttype = 0 OR a1.amprocrighttype = 0
OR p1.amprocnum < 0 OR p1.amproc = 0; OR a1.amprocnum < 0 OR a1.amproc = 0;
amprocfamily | amprocnum amprocfamily | amprocnum
--------------+----------- --------------+-----------
(0 rows) (0 rows)
@ -2129,20 +2129,20 @@ WHERE p1.amprocfamily = 0 OR p1.amproclefttype = 0 OR p1.amprocrighttype = 0
-- (else it suggests that the index ordering isn't fixed). But cross-type -- (else it suggests that the index ordering isn't fixed). But cross-type
-- members need only be stable, since they are just shorthands -- members need only be stable, since they are just shorthands
-- for index probe queries. -- for index probe queries.
SELECT p1.amprocfamily, p1.amproc, p2.prosrc SELECT a1.amprocfamily, a1.amproc, p1.prosrc
FROM pg_amproc AS p1, pg_proc AS p2 FROM pg_amproc AS a1, pg_proc AS p1
WHERE p1.amproc = p2.oid AND WHERE a1.amproc = p1.oid AND
p1.amproclefttype = p1.amprocrighttype AND a1.amproclefttype = a1.amprocrighttype AND
p2.provolatile != 'i'; p1.provolatile != 'i';
amprocfamily | amproc | prosrc amprocfamily | amproc | prosrc
--------------+--------+-------- --------------+--------+--------
(0 rows) (0 rows)
SELECT p1.amprocfamily, p1.amproc, p2.prosrc SELECT a1.amprocfamily, a1.amproc, p1.prosrc
FROM pg_amproc AS p1, pg_proc AS p2 FROM pg_amproc AS a1, pg_proc AS p1
WHERE p1.amproc = p2.oid AND WHERE a1.amproc = p1.oid AND
p1.amproclefttype != p1.amprocrighttype AND a1.amproclefttype != a1.amprocrighttype AND
p2.provolatile = 'v'; p1.provolatile = 'v';
amprocfamily | amproc | prosrc amprocfamily | amproc | prosrc
--------------+--------+-------- --------------+--------+--------
(0 rows) (0 rows)
@ -2186,17 +2186,17 @@ ORDER BY 1, 2, 3;
-- **************** pg_index **************** -- **************** pg_index ****************
-- Look for illegal values in pg_index fields. -- Look for illegal values in pg_index fields.
SELECT p1.indexrelid, p1.indrelid SELECT indexrelid, indrelid
FROM pg_index as p1 FROM pg_index
WHERE p1.indexrelid = 0 OR p1.indrelid = 0 OR WHERE indexrelid = 0 OR indrelid = 0 OR
p1.indnatts <= 0 OR p1.indnatts > 32; indnatts <= 0 OR indnatts > 32;
indexrelid | indrelid indexrelid | indrelid
------------+---------- ------------+----------
(0 rows) (0 rows)
-- oidvector and int2vector fields should be of length indnatts. -- oidvector and int2vector fields should be of length indnatts.
SELECT p1.indexrelid, p1.indrelid SELECT indexrelid, indrelid
FROM pg_index as p1 FROM pg_index
WHERE array_lower(indkey, 1) != 0 OR array_upper(indkey, 1) != indnatts-1 OR WHERE array_lower(indkey, 1) != 0 OR array_upper(indkey, 1) != indnatts-1 OR
array_lower(indclass, 1) != 0 OR array_upper(indclass, 1) != indnatts-1 OR array_lower(indclass, 1) != 0 OR array_upper(indclass, 1) != indnatts-1 OR
array_lower(indcollation, 1) != 0 OR array_upper(indcollation, 1) != indnatts-1 OR array_lower(indcollation, 1) != 0 OR array_upper(indcollation, 1) != indnatts-1 OR

View File

@ -13,45 +13,45 @@
-- field can't be 0, we have to check it here. -- field can't be 0, we have to check it here.
-- **************** pg_type **************** -- **************** pg_type ****************
-- Look for illegal values in pg_type fields. -- Look for illegal values in pg_type fields.
SELECT p1.oid, p1.typname SELECT t1.oid, t1.typname
FROM pg_type as p1 FROM pg_type as t1
WHERE p1.typnamespace = 0 OR WHERE t1.typnamespace = 0 OR
(p1.typlen <= 0 AND p1.typlen != -1 AND p1.typlen != -2) OR (t1.typlen <= 0 AND t1.typlen != -1 AND t1.typlen != -2) OR
(p1.typtype not in ('b', 'c', 'd', 'e', 'p', 'r', 'm')) OR (t1.typtype not in ('b', 'c', 'd', 'e', 'p', 'r', 'm')) OR
NOT p1.typisdefined OR NOT t1.typisdefined OR
(p1.typalign not in ('c', 's', 'i', 'd')) OR (t1.typalign not in ('c', 's', 'i', 'd')) OR
(p1.typstorage not in ('p', 'x', 'e', 'm')); (t1.typstorage not in ('p', 'x', 'e', 'm'));
oid | typname oid | typname
-----+--------- -----+---------
(0 rows) (0 rows)
-- Look for "pass by value" types that can't be passed by value. -- Look for "pass by value" types that can't be passed by value.
SELECT p1.oid, p1.typname SELECT t1.oid, t1.typname
FROM pg_type as p1 FROM pg_type as t1
WHERE p1.typbyval AND WHERE t1.typbyval AND
(p1.typlen != 1 OR p1.typalign != 'c') AND (t1.typlen != 1 OR t1.typalign != 'c') AND
(p1.typlen != 2 OR p1.typalign != 's') AND (t1.typlen != 2 OR t1.typalign != 's') AND
(p1.typlen != 4 OR p1.typalign != 'i') AND (t1.typlen != 4 OR t1.typalign != 'i') AND
(p1.typlen != 8 OR p1.typalign != 'd'); (t1.typlen != 8 OR t1.typalign != 'd');
oid | typname oid | typname
-----+--------- -----+---------
(0 rows) (0 rows)
-- Look for "toastable" types that aren't varlena. -- Look for "toastable" types that aren't varlena.
SELECT p1.oid, p1.typname SELECT t1.oid, t1.typname
FROM pg_type as p1 FROM pg_type as t1
WHERE p1.typstorage != 'p' AND WHERE t1.typstorage != 'p' AND
(p1.typbyval OR p1.typlen != -1); (t1.typbyval OR t1.typlen != -1);
oid | typname oid | typname
-----+--------- -----+---------
(0 rows) (0 rows)
-- Look for complex types that do not have a typrelid entry, -- Look for complex types that do not have a typrelid entry,
-- or basic types that do. -- or basic types that do.
SELECT p1.oid, p1.typname SELECT t1.oid, t1.typname
FROM pg_type as p1 FROM pg_type as t1
WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR WHERE (t1.typtype = 'c' AND t1.typrelid = 0) OR
(p1.typtype != 'c' AND p1.typrelid != 0); (t1.typtype != 'c' AND t1.typrelid != 0);
oid | typname oid | typname
-----+--------- -----+---------
(0 rows) (0 rows)
@ -59,14 +59,14 @@ WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR
-- Look for types that should have an array type but don't. -- Look for types that should have an array type but don't.
-- Generally anything that's not a pseudotype should have an array type. -- Generally anything that's not a pseudotype should have an array type.
-- However, we do have a small number of exceptions. -- However, we do have a small number of exceptions.
SELECT p1.oid, p1.typname SELECT t1.oid, t1.typname
FROM pg_type as p1 FROM pg_type as t1
WHERE p1.typtype not in ('p') AND p1.typname NOT LIKE E'\\_%' WHERE t1.typtype not in ('p') AND t1.typname NOT LIKE E'\\_%'
AND NOT EXISTS AND NOT EXISTS
(SELECT 1 FROM pg_type as p2 (SELECT 1 FROM pg_type as t2
WHERE p2.typname = ('_' || p1.typname)::name AND WHERE t2.typname = ('_' || t1.typname)::name AND
p2.typelem = p1.oid and p1.typarray = p2.oid) t2.typelem = t1.oid and t1.typarray = t2.oid)
ORDER BY p1.oid; ORDER BY t1.oid;
oid | typname oid | typname
------+------------------------------ ------+------------------------------
194 | pg_node_tree 194 | pg_node_tree
@ -78,56 +78,56 @@ ORDER BY p1.oid;
(6 rows) (6 rows)
-- Make sure typarray points to a "true" array type of our own base -- Make sure typarray points to a "true" array type of our own base
SELECT p1.oid, p1.typname as basetype, p2.typname as arraytype, SELECT t1.oid, t1.typname as basetype, t2.typname as arraytype,
p2.typsubscript t2.typsubscript
FROM pg_type p1 LEFT JOIN pg_type p2 ON (p1.typarray = p2.oid) FROM pg_type t1 LEFT JOIN pg_type t2 ON (t1.typarray = t2.oid)
WHERE p1.typarray <> 0 AND WHERE t1.typarray <> 0 AND
(p2.oid IS NULL OR (t2.oid IS NULL OR
p2.typsubscript <> 'array_subscript_handler'::regproc); t2.typsubscript <> 'array_subscript_handler'::regproc);
oid | basetype | arraytype | typsubscript oid | basetype | arraytype | typsubscript
-----+----------+-----------+-------------- -----+----------+-----------+--------------
(0 rows) (0 rows)
-- Look for range types that do not have a pg_range entry -- Look for range types that do not have a pg_range entry
SELECT p1.oid, p1.typname SELECT t1.oid, t1.typname
FROM pg_type as p1 FROM pg_type as t1
WHERE p1.typtype = 'r' AND WHERE t1.typtype = 'r' AND
NOT EXISTS(SELECT 1 FROM pg_range r WHERE rngtypid = p1.oid); NOT EXISTS(SELECT 1 FROM pg_range r WHERE rngtypid = t1.oid);
oid | typname oid | typname
-----+--------- -----+---------
(0 rows) (0 rows)
-- Look for range types whose typalign isn't sufficient -- Look for range types whose typalign isn't sufficient
SELECT p1.oid, p1.typname, p1.typalign, p2.typname, p2.typalign SELECT t1.oid, t1.typname, t1.typalign, t2.typname, t2.typalign
FROM pg_type as p1 FROM pg_type as t1
LEFT JOIN pg_range as r ON rngtypid = p1.oid LEFT JOIN pg_range as r ON rngtypid = t1.oid
LEFT JOIN pg_type as p2 ON rngsubtype = p2.oid LEFT JOIN pg_type as t2 ON rngsubtype = t2.oid
WHERE p1.typtype = 'r' AND WHERE t1.typtype = 'r' AND
(p1.typalign != (CASE WHEN p2.typalign = 'd' THEN 'd'::"char" (t1.typalign != (CASE WHEN t2.typalign = 'd' THEN 'd'::"char"
ELSE 'i'::"char" END) ELSE 'i'::"char" END)
OR p2.oid IS NULL); OR t2.oid IS NULL);
oid | typname | typalign | typname | typalign oid | typname | typalign | typname | typalign
-----+---------+----------+---------+---------- -----+---------+----------+---------+----------
(0 rows) (0 rows)
-- Text conversion routines must be provided. -- Text conversion routines must be provided.
SELECT p1.oid, p1.typname SELECT t1.oid, t1.typname
FROM pg_type as p1 FROM pg_type as t1
WHERE (p1.typinput = 0 OR p1.typoutput = 0); WHERE (t1.typinput = 0 OR t1.typoutput = 0);
oid | typname oid | typname
-----+--------- -----+---------
(0 rows) (0 rows)
-- Check for bogus typinput routines -- Check for bogus typinput routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typinput = p2.oid AND NOT WHERE t1.typinput = p1.oid AND NOT
((p2.pronargs = 1 AND p2.proargtypes[0] = 'cstring'::regtype) OR ((p1.pronargs = 1 AND p1.proargtypes[0] = 'cstring'::regtype) OR
(p2.pronargs = 2 AND p2.proargtypes[0] = 'cstring'::regtype AND (p1.pronargs = 2 AND p1.proargtypes[0] = 'cstring'::regtype AND
p2.proargtypes[1] = 'oid'::regtype) OR p1.proargtypes[1] = 'oid'::regtype) OR
(p2.pronargs = 3 AND p2.proargtypes[0] = 'cstring'::regtype AND (p1.pronargs = 3 AND p1.proargtypes[0] = 'cstring'::regtype AND
p2.proargtypes[1] = 'oid'::regtype AND p1.proargtypes[1] = 'oid'::regtype AND
p2.proargtypes[2] = 'int4'::regtype)); p1.proargtypes[2] = 'int4'::regtype));
oid | typname | oid | proname oid | typname | oid | proname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
@ -165,11 +165,11 @@ WHERE (proargmodes IS NOT NULL AND 'v' = any(proargmodes))
-- As of 8.0, this check finds refcursor, which is borrowing -- As of 8.0, this check finds refcursor, which is borrowing
-- other types' I/O routines -- other types' I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND NOT WHERE t1.typinput = p1.oid AND t1.typtype in ('b', 'p') AND NOT
(p1.typelem != 0 AND p1.typlen < 0) AND NOT (t1.typelem != 0 AND t1.typlen < 0) AND NOT
(p2.prorettype = p1.oid AND NOT p2.proretset) (p1.prorettype = t1.oid AND NOT p1.proretset)
ORDER BY 1; ORDER BY 1;
oid | typname | oid | proname oid | typname | oid | proname
------+-----------+-----+--------- ------+-----------+-----+---------
@ -178,11 +178,11 @@ ORDER BY 1;
-- Varlena array types will point to array_in -- Varlena array types will point to array_in
-- Exception as of 8.1: int2vector and oidvector have their own I/O routines -- Exception as of 8.1: int2vector and oidvector have their own I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typinput = p2.oid AND WHERE t1.typinput = p1.oid AND
(p1.typelem != 0 AND p1.typlen < 0) AND NOT (t1.typelem != 0 AND t1.typlen < 0) AND NOT
(p2.oid = 'array_in'::regproc) (p1.oid = 'array_in'::regproc)
ORDER BY 1; ORDER BY 1;
oid | typname | oid | proname oid | typname | oid | proname
-----+------------+-----+-------------- -----+------------+-----+--------------
@ -191,17 +191,17 @@ ORDER BY 1;
(2 rows) (2 rows)
-- typinput routines should not be volatile -- typinput routines should not be volatile
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typinput = p2.oid AND p2.provolatile NOT IN ('i', 's'); WHERE t1.typinput = p1.oid AND p1.provolatile NOT IN ('i', 's');
oid | typname | oid | proname oid | typname | oid | proname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- Composites, domains, enums, multiranges, ranges should all use the same input routines -- Composites, domains, enums, multiranges, ranges should all use the same input routines
SELECT DISTINCT typtype, typinput SELECT DISTINCT typtype, typinput
FROM pg_type AS p1 FROM pg_type AS t1
WHERE p1.typtype not in ('b', 'p') WHERE t1.typtype not in ('b', 'p')
ORDER BY 1; ORDER BY 1;
typtype | typinput typtype | typinput
---------+--------------- ---------+---------------
@ -215,39 +215,39 @@ ORDER BY 1;
-- Check for bogus typoutput routines -- Check for bogus typoutput routines
-- As of 8.0, this check finds refcursor, which is borrowing -- As of 8.0, this check finds refcursor, which is borrowing
-- other types' I/O routines -- other types' I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typoutput = p2.oid AND p1.typtype in ('b', 'p') AND NOT WHERE t1.typoutput = p1.oid AND t1.typtype in ('b', 'p') AND NOT
(p2.pronargs = 1 AND (p1.pronargs = 1 AND
(p2.proargtypes[0] = p1.oid OR (p1.proargtypes[0] = t1.oid OR
(p2.oid = 'array_out'::regproc AND (p1.oid = 'array_out'::regproc AND
p1.typelem != 0 AND p1.typlen = -1))) t1.typelem != 0 AND t1.typlen = -1)))
ORDER BY 1; ORDER BY 1;
oid | typname | oid | proname oid | typname | oid | proname
------+-----------+-----+--------- ------+-----------+-----+---------
1790 | refcursor | 47 | textout 1790 | refcursor | 47 | textout
(1 row) (1 row)
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typoutput = p2.oid AND NOT WHERE t1.typoutput = p1.oid AND NOT
(p2.prorettype = 'cstring'::regtype AND NOT p2.proretset); (p1.prorettype = 'cstring'::regtype AND NOT p1.proretset);
oid | typname | oid | proname oid | typname | oid | proname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- typoutput routines should not be volatile -- typoutput routines should not be volatile
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typoutput = p2.oid AND p2.provolatile NOT IN ('i', 's'); WHERE t1.typoutput = p1.oid AND p1.provolatile NOT IN ('i', 's');
oid | typname | oid | proname oid | typname | oid | proname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- Composites, enums, multiranges, ranges should all use the same output routines -- Composites, enums, multiranges, ranges should all use the same output routines
SELECT DISTINCT typtype, typoutput SELECT DISTINCT typtype, typoutput
FROM pg_type AS p1 FROM pg_type AS t1
WHERE p1.typtype not in ('b', 'd', 'p') WHERE t1.typtype not in ('b', 'd', 'p')
ORDER BY 1; ORDER BY 1;
typtype | typoutput typtype | typoutput
---------+---------------- ---------+----------------
@ -258,34 +258,34 @@ ORDER BY 1;
(4 rows) (4 rows)
-- Domains should have same typoutput as their base types -- Domains should have same typoutput as their base types
SELECT p1.oid, p1.typname, p2.oid, p2.typname SELECT t1.oid, t1.typname, t2.oid, t2.typname
FROM pg_type AS p1 LEFT JOIN pg_type AS p2 ON p1.typbasetype = p2.oid FROM pg_type AS t1 LEFT JOIN pg_type AS t2 ON t1.typbasetype = t2.oid
WHERE p1.typtype = 'd' AND p1.typoutput IS DISTINCT FROM p2.typoutput; WHERE t1.typtype = 'd' AND t1.typoutput IS DISTINCT FROM t2.typoutput;
oid | typname | oid | typname oid | typname | oid | typname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- Check for bogus typreceive routines -- Check for bogus typreceive routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typreceive = p2.oid AND NOT WHERE t1.typreceive = p1.oid AND NOT
((p2.pronargs = 1 AND p2.proargtypes[0] = 'internal'::regtype) OR ((p1.pronargs = 1 AND p1.proargtypes[0] = 'internal'::regtype) OR
(p2.pronargs = 2 AND p2.proargtypes[0] = 'internal'::regtype AND (p1.pronargs = 2 AND p1.proargtypes[0] = 'internal'::regtype AND
p2.proargtypes[1] = 'oid'::regtype) OR p1.proargtypes[1] = 'oid'::regtype) OR
(p2.pronargs = 3 AND p2.proargtypes[0] = 'internal'::regtype AND (p1.pronargs = 3 AND p1.proargtypes[0] = 'internal'::regtype AND
p2.proargtypes[1] = 'oid'::regtype AND p1.proargtypes[1] = 'oid'::regtype AND
p2.proargtypes[2] = 'int4'::regtype)); p1.proargtypes[2] = 'int4'::regtype));
oid | typname | oid | proname oid | typname | oid | proname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- As of 7.4, this check finds refcursor, which is borrowing -- As of 7.4, this check finds refcursor, which is borrowing
-- other types' I/O routines -- other types' I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND NOT WHERE t1.typreceive = p1.oid AND t1.typtype in ('b', 'p') AND NOT
(p1.typelem != 0 AND p1.typlen < 0) AND NOT (t1.typelem != 0 AND t1.typlen < 0) AND NOT
(p2.prorettype = p1.oid AND NOT p2.proretset) (p1.prorettype = t1.oid AND NOT p1.proretset)
ORDER BY 1; ORDER BY 1;
oid | typname | oid | proname oid | typname | oid | proname
------+-----------+------+---------- ------+-----------+------+----------
@ -294,11 +294,11 @@ ORDER BY 1;
-- Varlena array types will point to array_recv -- Varlena array types will point to array_recv
-- Exception as of 8.1: int2vector and oidvector have their own I/O routines -- Exception as of 8.1: int2vector and oidvector have their own I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typreceive = p2.oid AND WHERE t1.typreceive = p1.oid AND
(p1.typelem != 0 AND p1.typlen < 0) AND NOT (t1.typelem != 0 AND t1.typlen < 0) AND NOT
(p2.oid = 'array_recv'::regproc) (p1.oid = 'array_recv'::regproc)
ORDER BY 1; ORDER BY 1;
oid | typname | oid | proname oid | typname | oid | proname
-----+------------+------+---------------- -----+------------+------+----------------
@ -307,26 +307,26 @@ ORDER BY 1;
(2 rows) (2 rows)
-- Suspicious if typreceive doesn't take same number of args as typinput -- Suspicious if typreceive doesn't take same number of args as typinput
SELECT p1.oid, p1.typname, p2.oid, p2.proname, p3.oid, p3.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2, pg_proc AS p3 FROM pg_type AS t1, pg_proc AS p1, pg_proc AS p2
WHERE p1.typinput = p2.oid AND p1.typreceive = p3.oid AND WHERE t1.typinput = p1.oid AND t1.typreceive = p2.oid AND
p2.pronargs != p3.pronargs; p1.pronargs != p2.pronargs;
oid | typname | oid | proname | oid | proname oid | typname | oid | proname | oid | proname
-----+---------+-----+---------+-----+--------- -----+---------+-----+---------+-----+---------
(0 rows) (0 rows)
-- typreceive routines should not be volatile -- typreceive routines should not be volatile
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typreceive = p2.oid AND p2.provolatile NOT IN ('i', 's'); WHERE t1.typreceive = p1.oid AND p1.provolatile NOT IN ('i', 's');
oid | typname | oid | proname oid | typname | oid | proname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- Composites, domains, enums, multiranges, ranges should all use the same receive routines -- Composites, domains, enums, multiranges, ranges should all use the same receive routines
SELECT DISTINCT typtype, typreceive SELECT DISTINCT typtype, typreceive
FROM pg_type AS p1 FROM pg_type AS t1
WHERE p1.typtype not in ('b', 'p') WHERE t1.typtype not in ('b', 'p')
ORDER BY 1; ORDER BY 1;
typtype | typreceive typtype | typreceive
---------+----------------- ---------+-----------------
@ -340,39 +340,39 @@ ORDER BY 1;
-- Check for bogus typsend routines -- Check for bogus typsend routines
-- As of 7.4, this check finds refcursor, which is borrowing -- As of 7.4, this check finds refcursor, which is borrowing
-- other types' I/O routines -- other types' I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typsend = p2.oid AND p1.typtype in ('b', 'p') AND NOT WHERE t1.typsend = p1.oid AND t1.typtype in ('b', 'p') AND NOT
(p2.pronargs = 1 AND (p1.pronargs = 1 AND
(p2.proargtypes[0] = p1.oid OR (p1.proargtypes[0] = t1.oid OR
(p2.oid = 'array_send'::regproc AND (p1.oid = 'array_send'::regproc AND
p1.typelem != 0 AND p1.typlen = -1))) t1.typelem != 0 AND t1.typlen = -1)))
ORDER BY 1; ORDER BY 1;
oid | typname | oid | proname oid | typname | oid | proname
------+-----------+------+---------- ------+-----------+------+----------
1790 | refcursor | 2415 | textsend 1790 | refcursor | 2415 | textsend
(1 row) (1 row)
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typsend = p2.oid AND NOT WHERE t1.typsend = p1.oid AND NOT
(p2.prorettype = 'bytea'::regtype AND NOT p2.proretset); (p1.prorettype = 'bytea'::regtype AND NOT p1.proretset);
oid | typname | oid | proname oid | typname | oid | proname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- typsend routines should not be volatile -- typsend routines should not be volatile
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typsend = p2.oid AND p2.provolatile NOT IN ('i', 's'); WHERE t1.typsend = p1.oid AND p1.provolatile NOT IN ('i', 's');
oid | typname | oid | proname oid | typname | oid | proname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- Composites, enums, multiranges, ranges should all use the same send routines -- Composites, enums, multiranges, ranges should all use the same send routines
SELECT DISTINCT typtype, typsend SELECT DISTINCT typtype, typsend
FROM pg_type AS p1 FROM pg_type AS t1
WHERE p1.typtype not in ('b', 'd', 'p') WHERE t1.typtype not in ('b', 'd', 'p')
ORDER BY 1; ORDER BY 1;
typtype | typsend typtype | typsend
---------+----------------- ---------+-----------------
@ -383,112 +383,112 @@ ORDER BY 1;
(4 rows) (4 rows)
-- Domains should have same typsend as their base types -- Domains should have same typsend as their base types
SELECT p1.oid, p1.typname, p2.oid, p2.typname SELECT t1.oid, t1.typname, t2.oid, t2.typname
FROM pg_type AS p1 LEFT JOIN pg_type AS p2 ON p1.typbasetype = p2.oid FROM pg_type AS t1 LEFT JOIN pg_type AS t2 ON t1.typbasetype = t2.oid
WHERE p1.typtype = 'd' AND p1.typsend IS DISTINCT FROM p2.typsend; WHERE t1.typtype = 'd' AND t1.typsend IS DISTINCT FROM t2.typsend;
oid | typname | oid | typname oid | typname | oid | typname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- Check for bogus typmodin routines -- Check for bogus typmodin routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typmodin = p2.oid AND NOT WHERE t1.typmodin = p1.oid AND NOT
(p2.pronargs = 1 AND (p1.pronargs = 1 AND
p2.proargtypes[0] = 'cstring[]'::regtype AND p1.proargtypes[0] = 'cstring[]'::regtype AND
p2.prorettype = 'int4'::regtype AND NOT p2.proretset); p1.prorettype = 'int4'::regtype AND NOT p1.proretset);
oid | typname | oid | proname oid | typname | oid | proname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- typmodin routines should not be volatile -- typmodin routines should not be volatile
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typmodin = p2.oid AND p2.provolatile NOT IN ('i', 's'); WHERE t1.typmodin = p1.oid AND p1.provolatile NOT IN ('i', 's');
oid | typname | oid | proname oid | typname | oid | proname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- Check for bogus typmodout routines -- Check for bogus typmodout routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typmodout = p2.oid AND NOT WHERE t1.typmodout = p1.oid AND NOT
(p2.pronargs = 1 AND (p1.pronargs = 1 AND
p2.proargtypes[0] = 'int4'::regtype AND p1.proargtypes[0] = 'int4'::regtype AND
p2.prorettype = 'cstring'::regtype AND NOT p2.proretset); p1.prorettype = 'cstring'::regtype AND NOT p1.proretset);
oid | typname | oid | proname oid | typname | oid | proname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- typmodout routines should not be volatile -- typmodout routines should not be volatile
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typmodout = p2.oid AND p2.provolatile NOT IN ('i', 's'); WHERE t1.typmodout = p1.oid AND p1.provolatile NOT IN ('i', 's');
oid | typname | oid | proname oid | typname | oid | proname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- Array types should have same typmodin/out as their element types -- Array types should have same typmodin/out as their element types
SELECT p1.oid, p1.typname, p2.oid, p2.typname SELECT t1.oid, t1.typname, t2.oid, t2.typname
FROM pg_type AS p1, pg_type AS p2 FROM pg_type AS t1, pg_type AS t2
WHERE p1.typelem = p2.oid AND NOT WHERE t1.typelem = t2.oid AND NOT
(p1.typmodin = p2.typmodin AND p1.typmodout = p2.typmodout); (t1.typmodin = t2.typmodin AND t1.typmodout = t2.typmodout);
oid | typname | oid | typname oid | typname | oid | typname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- Array types should have same typdelim as their element types -- Array types should have same typdelim as their element types
SELECT p1.oid, p1.typname, p2.oid, p2.typname SELECT t1.oid, t1.typname, t2.oid, t2.typname
FROM pg_type AS p1, pg_type AS p2 FROM pg_type AS t1, pg_type AS t2
WHERE p1.typarray = p2.oid AND NOT (p1.typdelim = p2.typdelim); WHERE t1.typarray = t2.oid AND NOT (t1.typdelim = t2.typdelim);
oid | typname | oid | typname oid | typname | oid | typname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- Look for array types whose typalign isn't sufficient -- Look for array types whose typalign isn't sufficient
SELECT p1.oid, p1.typname, p1.typalign, p2.typname, p2.typalign SELECT t1.oid, t1.typname, t1.typalign, t2.typname, t2.typalign
FROM pg_type AS p1, pg_type AS p2 FROM pg_type AS t1, pg_type AS t2
WHERE p1.typarray = p2.oid AND WHERE t1.typarray = t2.oid AND
p2.typalign != (CASE WHEN p1.typalign = 'd' THEN 'd'::"char" t2.typalign != (CASE WHEN t1.typalign = 'd' THEN 'd'::"char"
ELSE 'i'::"char" END); ELSE 'i'::"char" END);
oid | typname | typalign | typname | typalign oid | typname | typalign | typname | typalign
-----+---------+----------+---------+---------- -----+---------+----------+---------+----------
(0 rows) (0 rows)
-- Check for typelem set without a handler -- Check for typelem set without a handler
SELECT p1.oid, p1.typname, p1.typelem SELECT t1.oid, t1.typname, t1.typelem
FROM pg_type AS p1 FROM pg_type AS t1
WHERE p1.typelem != 0 AND p1.typsubscript = 0; WHERE t1.typelem != 0 AND t1.typsubscript = 0;
oid | typname | typelem oid | typname | typelem
-----+---------+--------- -----+---------+---------
(0 rows) (0 rows)
-- Check for misuse of standard subscript handlers -- Check for misuse of standard subscript handlers
SELECT p1.oid, p1.typname, SELECT t1.oid, t1.typname,
p1.typelem, p1.typlen, p1.typbyval t1.typelem, t1.typlen, t1.typbyval
FROM pg_type AS p1 FROM pg_type AS t1
WHERE p1.typsubscript = 'array_subscript_handler'::regproc AND NOT WHERE t1.typsubscript = 'array_subscript_handler'::regproc AND NOT
(p1.typelem != 0 AND p1.typlen = -1 AND NOT p1.typbyval); (t1.typelem != 0 AND t1.typlen = -1 AND NOT t1.typbyval);
oid | typname | typelem | typlen | typbyval oid | typname | typelem | typlen | typbyval
-----+---------+---------+--------+---------- -----+---------+---------+--------+----------
(0 rows) (0 rows)
SELECT p1.oid, p1.typname, SELECT t1.oid, t1.typname,
p1.typelem, p1.typlen, p1.typbyval t1.typelem, t1.typlen, t1.typbyval
FROM pg_type AS p1 FROM pg_type AS t1
WHERE p1.typsubscript = 'raw_array_subscript_handler'::regproc AND NOT WHERE t1.typsubscript = 'raw_array_subscript_handler'::regproc AND NOT
(p1.typelem != 0 AND p1.typlen > 0 AND NOT p1.typbyval); (t1.typelem != 0 AND t1.typlen > 0 AND NOT t1.typbyval);
oid | typname | typelem | typlen | typbyval oid | typname | typelem | typlen | typbyval
-----+---------+---------+--------+---------- -----+---------+---------+--------+----------
(0 rows) (0 rows)
-- Check for bogus typanalyze routines -- Check for bogus typanalyze routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typanalyze = p2.oid AND NOT WHERE t1.typanalyze = p1.oid AND NOT
(p2.pronargs = 1 AND (p1.pronargs = 1 AND
p2.proargtypes[0] = 'internal'::regtype AND p1.proargtypes[0] = 'internal'::regtype AND
p2.prorettype = 'bool'::regtype AND NOT p2.proretset); p1.prorettype = 'bool'::regtype AND NOT p1.proretset);
oid | typname | oid | proname oid | typname | oid | proname
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
@ -529,8 +529,8 @@ ORDER BY 1;
-- **************** pg_class **************** -- **************** pg_class ****************
-- Look for illegal values in pg_class fields -- Look for illegal values in pg_class fields
SELECT p1.oid, p1.relname SELECT c1.oid, c1.relname
FROM pg_class as p1 FROM pg_class as c1
WHERE relkind NOT IN ('r', 'i', 'S', 't', 'v', 'm', 'c', 'f', 'p') OR WHERE relkind NOT IN ('r', 'i', 'S', 't', 'v', 'm', 'c', 'f', 'p') OR
relpersistence NOT IN ('p', 'u', 't') OR relpersistence NOT IN ('p', 'u', 't') OR
relreplident NOT IN ('d', 'n', 'f', 'i'); relreplident NOT IN ('d', 'n', 'f', 'i');
@ -539,19 +539,19 @@ WHERE relkind NOT IN ('r', 'i', 'S', 't', 'v', 'm', 'c', 'f', 'p') OR
(0 rows) (0 rows)
-- All tables and indexes should have an access method. -- All tables and indexes should have an access method.
SELECT p1.oid, p1.relname SELECT c1.oid, c1.relname
FROM pg_class as p1 FROM pg_class as c1
WHERE p1.relkind NOT IN ('S', 'v', 'f', 'c') and WHERE c1.relkind NOT IN ('S', 'v', 'f', 'c') and
p1.relam = 0; c1.relam = 0;
oid | relname oid | relname
-----+--------- -----+---------
(0 rows) (0 rows)
-- Conversely, sequences, views, types shouldn't have them -- Conversely, sequences, views, types shouldn't have them
SELECT p1.oid, p1.relname SELECT c1.oid, c1.relname
FROM pg_class as p1 FROM pg_class as c1
WHERE p1.relkind IN ('S', 'v', 'f', 'c') and WHERE c1.relkind IN ('S', 'v', 'f', 'c') and
p1.relam != 0; c1.relam != 0;
oid | relname oid | relname
-----+--------- -----+---------
(0 rows) (0 rows)
@ -576,29 +576,29 @@ WHERE pc.relkind IN ('r', 't', 'm') and
-- **************** pg_attribute **************** -- **************** pg_attribute ****************
-- Look for illegal values in pg_attribute fields -- Look for illegal values in pg_attribute fields
SELECT p1.attrelid, p1.attname SELECT a1.attrelid, a1.attname
FROM pg_attribute as p1 FROM pg_attribute as a1
WHERE p1.attrelid = 0 OR p1.atttypid = 0 OR p1.attnum = 0 OR WHERE a1.attrelid = 0 OR a1.atttypid = 0 OR a1.attnum = 0 OR
p1.attcacheoff != -1 OR p1.attinhcount < 0 OR a1.attcacheoff != -1 OR a1.attinhcount < 0 OR
(p1.attinhcount = 0 AND NOT p1.attislocal); (a1.attinhcount = 0 AND NOT a1.attislocal);
attrelid | attname attrelid | attname
----------+--------- ----------+---------
(0 rows) (0 rows)
-- Cross-check attnum against parent relation -- Cross-check attnum against parent relation
SELECT p1.attrelid, p1.attname, p2.oid, p2.relname SELECT a1.attrelid, a1.attname, c1.oid, c1.relname
FROM pg_attribute AS p1, pg_class AS p2 FROM pg_attribute AS a1, pg_class AS c1
WHERE p1.attrelid = p2.oid AND p1.attnum > p2.relnatts; WHERE a1.attrelid = c1.oid AND a1.attnum > c1.relnatts;
attrelid | attname | oid | relname attrelid | attname | oid | relname
----------+---------+-----+--------- ----------+---------+-----+---------
(0 rows) (0 rows)
-- Detect missing pg_attribute entries: should have as many non-system -- Detect missing pg_attribute entries: should have as many non-system
-- attributes as parent relation expects -- attributes as parent relation expects
SELECT p1.oid, p1.relname SELECT c1.oid, c1.relname
FROM pg_class AS p1 FROM pg_class AS c1
WHERE p1.relnatts != (SELECT count(*) FROM pg_attribute AS p2 WHERE c1.relnatts != (SELECT count(*) FROM pg_attribute AS a1
WHERE p2.attrelid = p1.oid AND p2.attnum > 0); WHERE a1.attrelid = c1.oid AND a1.attnum > 0);
oid | relname oid | relname
-----+--------- -----+---------
(0 rows) (0 rows)
@ -606,29 +606,29 @@ WHERE p1.relnatts != (SELECT count(*) FROM pg_attribute AS p2
-- Cross-check against pg_type entry -- Cross-check against pg_type entry
-- NOTE: we allow attstorage to be 'plain' even when typstorage is not; -- NOTE: we allow attstorage to be 'plain' even when typstorage is not;
-- this is mainly for toast tables. -- this is mainly for toast tables.
SELECT p1.attrelid, p1.attname, p2.oid, p2.typname SELECT a1.attrelid, a1.attname, t1.oid, t1.typname
FROM pg_attribute AS p1, pg_type AS p2 FROM pg_attribute AS a1, pg_type AS t1
WHERE p1.atttypid = p2.oid AND WHERE a1.atttypid = t1.oid AND
(p1.attlen != p2.typlen OR (a1.attlen != t1.typlen OR
p1.attalign != p2.typalign OR a1.attalign != t1.typalign OR
p1.attbyval != p2.typbyval OR a1.attbyval != t1.typbyval OR
(p1.attstorage != p2.typstorage AND p1.attstorage != 'p')); (a1.attstorage != t1.typstorage AND a1.attstorage != 'p'));
attrelid | attname | oid | typname attrelid | attname | oid | typname
----------+---------+-----+--------- ----------+---------+-----+---------
(0 rows) (0 rows)
-- **************** pg_range **************** -- **************** pg_range ****************
-- Look for illegal values in pg_range fields. -- Look for illegal values in pg_range fields.
SELECT p1.rngtypid, p1.rngsubtype SELECT r.rngtypid, r.rngsubtype
FROM pg_range as p1 FROM pg_range as r
WHERE p1.rngtypid = 0 OR p1.rngsubtype = 0 OR p1.rngsubopc = 0; WHERE r.rngtypid = 0 OR r.rngsubtype = 0 OR r.rngsubopc = 0;
rngtypid | rngsubtype rngtypid | rngsubtype
----------+------------ ----------+------------
(0 rows) (0 rows)
-- rngcollation should be specified iff subtype is collatable -- rngcollation should be specified iff subtype is collatable
SELECT p1.rngtypid, p1.rngsubtype, p1.rngcollation, t.typcollation SELECT r.rngtypid, r.rngsubtype, r.rngcollation, t.typcollation
FROM pg_range p1 JOIN pg_type t ON t.oid = p1.rngsubtype FROM pg_range r JOIN pg_type t ON t.oid = r.rngsubtype
WHERE (rngcollation = 0) != (typcollation = 0); WHERE (rngcollation = 0) != (typcollation = 0);
rngtypid | rngsubtype | rngcollation | typcollation rngtypid | rngsubtype | rngcollation | typcollation
----------+------------+--------------+-------------- ----------+------------+--------------+--------------
@ -636,29 +636,29 @@ WHERE (rngcollation = 0) != (typcollation = 0);
-- opclass had better be a btree opclass accepting the subtype. -- opclass had better be a btree opclass accepting the subtype.
-- We must allow anyarray matches, cf IsBinaryCoercible() -- We must allow anyarray matches, cf IsBinaryCoercible()
SELECT p1.rngtypid, p1.rngsubtype, o.opcmethod, o.opcname SELECT r.rngtypid, r.rngsubtype, o.opcmethod, o.opcname
FROM pg_range p1 JOIN pg_opclass o ON o.oid = p1.rngsubopc FROM pg_range r JOIN pg_opclass o ON o.oid = r.rngsubopc
WHERE o.opcmethod != 403 OR WHERE o.opcmethod != 403 OR
((o.opcintype != p1.rngsubtype) AND NOT ((o.opcintype != r.rngsubtype) AND NOT
(o.opcintype = 'pg_catalog.anyarray'::regtype AND (o.opcintype = 'pg_catalog.anyarray'::regtype AND
EXISTS(select 1 from pg_catalog.pg_type where EXISTS(select 1 from pg_catalog.pg_type where
oid = p1.rngsubtype and typelem != 0 and oid = r.rngsubtype and typelem != 0 and
typsubscript = 'array_subscript_handler'::regproc))); typsubscript = 'array_subscript_handler'::regproc)));
rngtypid | rngsubtype | opcmethod | opcname rngtypid | rngsubtype | opcmethod | opcname
----------+------------+-----------+--------- ----------+------------+-----------+---------
(0 rows) (0 rows)
-- canonical function, if any, had better match the range type -- canonical function, if any, had better match the range type
SELECT p1.rngtypid, p1.rngsubtype, p.proname SELECT r.rngtypid, r.rngsubtype, p.proname
FROM pg_range p1 JOIN pg_proc p ON p.oid = p1.rngcanonical FROM pg_range r JOIN pg_proc p ON p.oid = r.rngcanonical
WHERE pronargs != 1 OR proargtypes[0] != rngtypid OR prorettype != rngtypid; WHERE pronargs != 1 OR proargtypes[0] != rngtypid OR prorettype != rngtypid;
rngtypid | rngsubtype | proname rngtypid | rngsubtype | proname
----------+------------+--------- ----------+------------+---------
(0 rows) (0 rows)
-- subdiff function, if any, had better match the subtype -- subdiff function, if any, had better match the subtype
SELECT p1.rngtypid, p1.rngsubtype, p.proname SELECT r.rngtypid, r.rngsubtype, p.proname
FROM pg_range p1 JOIN pg_proc p ON p.oid = p1.rngsubdiff FROM pg_range r JOIN pg_proc p ON p.oid = r.rngsubdiff
WHERE pronargs != 2 WHERE pronargs != 2
OR proargtypes[0] != rngsubtype OR proargtypes[1] != rngsubtype OR proargtypes[0] != rngsubtype OR proargtypes[1] != rngsubtype
OR prorettype != 'pg_catalog.float8'::regtype; OR prorettype != 'pg_catalog.float8'::regtype;
@ -667,9 +667,9 @@ WHERE pronargs != 2
(0 rows) (0 rows)
-- every range should have a valid multirange -- every range should have a valid multirange
SELECT p1.rngtypid, p1.rngsubtype, p1.rngmultitypid SELECT r.rngtypid, r.rngsubtype, r.rngmultitypid
FROM pg_range p1 FROM pg_range r
WHERE p1.rngmultitypid IS NULL OR p1.rngmultitypid = 0; WHERE r.rngmultitypid IS NULL OR r.rngmultitypid = 0;
rngtypid | rngsubtype | rngmultitypid rngtypid | rngsubtype | rngmultitypid
----------+------------+--------------- ----------+------------+---------------
(0 rows) (0 rows)

View File

@ -489,9 +489,9 @@ WHERE c.castmethod = 'b' AND
-- Look for illegal values in pg_conversion fields. -- Look for illegal values in pg_conversion fields.
SELECT p1.oid, p1.conname SELECT c.oid, c.conname
FROM pg_conversion as p1 FROM pg_conversion as c
WHERE p1.conproc = 0 OR WHERE c.conproc = 0 OR
pg_encoding_to_char(conforencoding) = '' OR pg_encoding_to_char(conforencoding) = '' OR
pg_encoding_to_char(contoencoding) = ''; pg_encoding_to_char(contoencoding) = '';
@ -519,8 +519,8 @@ WHERE p.oid = c.conproc AND
-- conversions anyway. -- conversions anyway.
-- (Similarly, this doesn't cope with any search path issues.) -- (Similarly, this doesn't cope with any search path issues.)
SELECT p1.oid, p1.conname SELECT c.oid, c.conname
FROM pg_conversion as p1 FROM pg_conversion as c
WHERE condefault AND WHERE condefault AND
convert('ABC'::bytea, pg_encoding_to_char(conforencoding), convert('ABC'::bytea, pg_encoding_to_char(conforencoding),
pg_encoding_to_char(contoencoding)) != 'ABC'; pg_encoding_to_char(contoencoding)) != 'ABC';
@ -530,42 +530,42 @@ WHERE condefault AND
-- Look for illegal values in pg_operator fields. -- Look for illegal values in pg_operator fields.
SELECT p1.oid, p1.oprname SELECT o1.oid, o1.oprname
FROM pg_operator as p1 FROM pg_operator as o1
WHERE (p1.oprkind != 'b' AND p1.oprkind != 'l') OR WHERE (o1.oprkind != 'b' AND o1.oprkind != 'l') OR
p1.oprresult = 0 OR p1.oprcode = 0; o1.oprresult = 0 OR o1.oprcode = 0;
-- Look for missing or unwanted operand types -- Look for missing or unwanted operand types
SELECT p1.oid, p1.oprname SELECT o1.oid, o1.oprname
FROM pg_operator as p1 FROM pg_operator as o1
WHERE (p1.oprleft = 0 and p1.oprkind != 'l') OR WHERE (o1.oprleft = 0 and o1.oprkind != 'l') OR
(p1.oprleft != 0 and p1.oprkind = 'l') OR (o1.oprleft != 0 and o1.oprkind = 'l') OR
p1.oprright = 0; o1.oprright = 0;
-- Look for conflicting operator definitions (same names and input datatypes). -- Look for conflicting operator definitions (same names and input datatypes).
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode
FROM pg_operator AS p1, pg_operator AS p2 FROM pg_operator AS o1, pg_operator AS o2
WHERE p1.oid != p2.oid AND WHERE o1.oid != o2.oid AND
p1.oprname = p2.oprname AND o1.oprname = o2.oprname AND
p1.oprkind = p2.oprkind AND o1.oprkind = o2.oprkind AND
p1.oprleft = p2.oprleft AND o1.oprleft = o2.oprleft AND
p1.oprright = p2.oprright; o1.oprright = o2.oprright;
-- Look for commutative operators that don't commute. -- Look for commutative operators that don't commute.
-- DEFINITIONAL NOTE: If A.oprcom = B, then x A y has the same result as y B x. -- DEFINITIONAL NOTE: If A.oprcom = B, then x A y has the same result as y B x.
-- We expect that B will always say that B.oprcom = A as well; that's not -- We expect that B will always say that B.oprcom = A as well; that's not
-- inherently essential, but it would be inefficient not to mark it so. -- inherently essential, but it would be inefficient not to mark it so.
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode
FROM pg_operator AS p1, pg_operator AS p2 FROM pg_operator AS o1, pg_operator AS o2
WHERE p1.oprcom = p2.oid AND WHERE o1.oprcom = o2.oid AND
(p1.oprkind != 'b' OR (o1.oprkind != 'b' OR
p1.oprleft != p2.oprright OR o1.oprleft != o2.oprright OR
p1.oprright != p2.oprleft OR o1.oprright != o2.oprleft OR
p1.oprresult != p2.oprresult OR o1.oprresult != o2.oprresult OR
p1.oid != p2.oprcom); o1.oid != o2.oprcom);
-- Look for negatory operators that don't agree. -- Look for negatory operators that don't agree.
-- DEFINITIONAL NOTE: If A.oprnegate = B, then both A and B must yield -- DEFINITIONAL NOTE: If A.oprnegate = B, then both A and B must yield
@ -575,16 +575,16 @@ WHERE p1.oprcom = p2.oid AND
-- inherently essential, but it would be inefficient not to mark it so. -- inherently essential, but it would be inefficient not to mark it so.
-- Also, A and B had better not be the same operator. -- Also, A and B had better not be the same operator.
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode
FROM pg_operator AS p1, pg_operator AS p2 FROM pg_operator AS o1, pg_operator AS o2
WHERE p1.oprnegate = p2.oid AND WHERE o1.oprnegate = o2.oid AND
(p1.oprkind != p2.oprkind OR (o1.oprkind != o2.oprkind OR
p1.oprleft != p2.oprleft OR o1.oprleft != o2.oprleft OR
p1.oprright != p2.oprright OR o1.oprright != o2.oprright OR
p1.oprresult != 'bool'::regtype OR o1.oprresult != 'bool'::regtype OR
p2.oprresult != 'bool'::regtype OR o2.oprresult != 'bool'::regtype OR
p1.oid != p2.oprnegate OR o1.oid != o2.oprnegate OR
p1.oid = p2.oid); o1.oid = o2.oid);
-- Make a list of the names of operators that are claimed to be commutator -- Make a list of the names of operators that are claimed to be commutator
-- pairs. This list will grow over time, but before accepting a new entry -- pairs. This list will grow over time, but before accepting a new entry
@ -606,93 +606,93 @@ ORDER BY 1, 2;
-- boolean, and must have a commutator (itself, unless it's a cross-type -- boolean, and must have a commutator (itself, unless it's a cross-type
-- operator). -- operator).
SELECT p1.oid, p1.oprname FROM pg_operator AS p1 SELECT o1.oid, o1.oprname FROM pg_operator AS o1
WHERE (p1.oprcanmerge OR p1.oprcanhash) AND NOT WHERE (o1.oprcanmerge OR o1.oprcanhash) AND NOT
(p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND p1.oprcom != 0); (o1.oprkind = 'b' AND o1.oprresult = 'bool'::regtype AND o1.oprcom != 0);
-- What's more, the commutator had better be mergejoinable/hashjoinable too. -- What's more, the commutator had better be mergejoinable/hashjoinable too.
SELECT p1.oid, p1.oprname, p2.oid, p2.oprname SELECT o1.oid, o1.oprname, o2.oid, o2.oprname
FROM pg_operator AS p1, pg_operator AS p2 FROM pg_operator AS o1, pg_operator AS o2
WHERE p1.oprcom = p2.oid AND WHERE o1.oprcom = o2.oid AND
(p1.oprcanmerge != p2.oprcanmerge OR (o1.oprcanmerge != o2.oprcanmerge OR
p1.oprcanhash != p2.oprcanhash); o1.oprcanhash != o2.oprcanhash);
-- Mergejoinable operators should appear as equality members of btree index -- Mergejoinable operators should appear as equality members of btree index
-- opfamilies. -- opfamilies.
SELECT p1.oid, p1.oprname SELECT o1.oid, o1.oprname
FROM pg_operator AS p1 FROM pg_operator AS o1
WHERE p1.oprcanmerge AND NOT EXISTS WHERE o1.oprcanmerge AND NOT EXISTS
(SELECT 1 FROM pg_amop (SELECT 1 FROM pg_amop
WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND
amopopr = p1.oid AND amopstrategy = 3); amopopr = o1.oid AND amopstrategy = 3);
-- And the converse. -- And the converse.
SELECT p1.oid, p1.oprname, p.amopfamily SELECT o1.oid, o1.oprname, p.amopfamily
FROM pg_operator AS p1, pg_amop p FROM pg_operator AS o1, pg_amop p
WHERE amopopr = p1.oid WHERE amopopr = o1.oid
AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree')
AND amopstrategy = 3 AND amopstrategy = 3
AND NOT p1.oprcanmerge; AND NOT o1.oprcanmerge;
-- Hashable operators should appear as members of hash index opfamilies. -- Hashable operators should appear as members of hash index opfamilies.
SELECT p1.oid, p1.oprname SELECT o1.oid, o1.oprname
FROM pg_operator AS p1 FROM pg_operator AS o1
WHERE p1.oprcanhash AND NOT EXISTS WHERE o1.oprcanhash AND NOT EXISTS
(SELECT 1 FROM pg_amop (SELECT 1 FROM pg_amop
WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND
amopopr = p1.oid AND amopstrategy = 1); amopopr = o1.oid AND amopstrategy = 1);
-- And the converse. -- And the converse.
SELECT p1.oid, p1.oprname, p.amopfamily SELECT o1.oid, o1.oprname, p.amopfamily
FROM pg_operator AS p1, pg_amop p FROM pg_operator AS o1, pg_amop p
WHERE amopopr = p1.oid WHERE amopopr = o1.oid
AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash')
AND NOT p1.oprcanhash; AND NOT o1.oprcanhash;
-- Check that each operator defined in pg_operator matches its oprcode entry -- Check that each operator defined in pg_operator matches its oprcode entry
-- in pg_proc. Easiest to do this separately for each oprkind. -- in pg_proc. Easiest to do this separately for each oprkind.
SELECT p1.oid, p1.oprname, p2.oid, p2.proname SELECT o1.oid, o1.oprname, p1.oid, p1.proname
FROM pg_operator AS p1, pg_proc AS p2 FROM pg_operator AS o1, pg_proc AS p1
WHERE p1.oprcode = p2.oid AND WHERE o1.oprcode = p1.oid AND
p1.oprkind = 'b' AND o1.oprkind = 'b' AND
(p2.pronargs != 2 (p1.pronargs != 2
OR NOT binary_coercible(p2.prorettype, p1.oprresult) OR NOT binary_coercible(p1.prorettype, o1.oprresult)
OR NOT binary_coercible(p1.oprleft, p2.proargtypes[0]) OR NOT binary_coercible(o1.oprleft, p1.proargtypes[0])
OR NOT binary_coercible(p1.oprright, p2.proargtypes[1])); OR NOT binary_coercible(o1.oprright, p1.proargtypes[1]));
SELECT p1.oid, p1.oprname, p2.oid, p2.proname SELECT o1.oid, o1.oprname, p1.oid, p1.proname
FROM pg_operator AS p1, pg_proc AS p2 FROM pg_operator AS o1, pg_proc AS p1
WHERE p1.oprcode = p2.oid AND WHERE o1.oprcode = p1.oid AND
p1.oprkind = 'l' AND o1.oprkind = 'l' AND
(p2.pronargs != 1 (p1.pronargs != 1
OR NOT binary_coercible(p2.prorettype, p1.oprresult) OR NOT binary_coercible(p1.prorettype, o1.oprresult)
OR NOT binary_coercible(p1.oprright, p2.proargtypes[0]) OR NOT binary_coercible(o1.oprright, p1.proargtypes[0])
OR p1.oprleft != 0); OR o1.oprleft != 0);
-- If the operator is mergejoinable or hashjoinable, its underlying function -- If the operator is mergejoinable or hashjoinable, its underlying function
-- should not be volatile. -- should not be volatile.
SELECT p1.oid, p1.oprname, p2.oid, p2.proname SELECT o1.oid, o1.oprname, p1.oid, p1.proname
FROM pg_operator AS p1, pg_proc AS p2 FROM pg_operator AS o1, pg_proc AS p1
WHERE p1.oprcode = p2.oid AND WHERE o1.oprcode = p1.oid AND
(p1.oprcanmerge OR p1.oprcanhash) AND (o1.oprcanmerge OR o1.oprcanhash) AND
p2.provolatile = 'v'; p1.provolatile = 'v';
-- If oprrest is set, the operator must return boolean, -- If oprrest is set, the operator must return boolean,
-- and it must link to a proc with the right signature -- and it must link to a proc with the right signature
-- to be a restriction selectivity estimator. -- to be a restriction selectivity estimator.
-- The proc signature we want is: float8 proc(internal, oid, internal, int4) -- The proc signature we want is: float8 proc(internal, oid, internal, int4)
SELECT p1.oid, p1.oprname, p2.oid, p2.proname SELECT o1.oid, o1.oprname, p2.oid, p2.proname
FROM pg_operator AS p1, pg_proc AS p2 FROM pg_operator AS o1, pg_proc AS p2
WHERE p1.oprrest = p2.oid AND WHERE o1.oprrest = p2.oid AND
(p1.oprresult != 'bool'::regtype OR (o1.oprresult != 'bool'::regtype OR
p2.prorettype != 'float8'::regtype OR p2.proretset OR p2.prorettype != 'float8'::regtype OR p2.proretset OR
p2.pronargs != 4 OR p2.pronargs != 4 OR
p2.proargtypes[0] != 'internal'::regtype OR p2.proargtypes[0] != 'internal'::regtype OR
@ -707,10 +707,10 @@ WHERE p1.oprrest = p2.oid AND
-- (Note: the old signature with only 4 args is still allowed, but no core -- (Note: the old signature with only 4 args is still allowed, but no core
-- estimator should be using it.) -- estimator should be using it.)
SELECT p1.oid, p1.oprname, p2.oid, p2.proname SELECT o1.oid, o1.oprname, p2.oid, p2.proname
FROM pg_operator AS p1, pg_proc AS p2 FROM pg_operator AS o1, pg_proc AS p2
WHERE p1.oprjoin = p2.oid AND WHERE o1.oprjoin = p2.oid AND
(p1.oprkind != 'b' OR p1.oprresult != 'bool'::regtype OR (o1.oprkind != 'b' OR o1.oprresult != 'bool'::regtype OR
p2.prorettype != 'float8'::regtype OR p2.proretset OR p2.prorettype != 'float8'::regtype OR p2.proretset OR
p2.pronargs != 5 OR p2.pronargs != 5 OR
p2.proargtypes[0] != 'internal'::regtype OR p2.proargtypes[0] != 'internal'::regtype OR
@ -720,10 +720,10 @@ WHERE p1.oprjoin = p2.oid AND
p2.proargtypes[4] != 'internal'::regtype); p2.proargtypes[4] != 'internal'::regtype);
-- Insist that all built-in pg_operator entries have descriptions -- Insist that all built-in pg_operator entries have descriptions
SELECT p1.oid, p1.oprname SELECT o1.oid, o1.oprname
FROM pg_operator as p1 LEFT JOIN pg_description as d FROM pg_operator as o1 LEFT JOIN pg_description as d
ON p1.tableoid = d.classoid and p1.oid = d.objoid and d.objsubid = 0 ON o1.tableoid = d.classoid and o1.oid = d.objoid and d.objsubid = 0
WHERE d.classoid IS NULL AND p1.oid <= 9999; WHERE d.classoid IS NULL AND o1.oid <= 9999;
-- Check that operators' underlying functions have suitable comments, -- Check that operators' underlying functions have suitable comments,
-- namely 'implementation of XXX operator'. (Note: it's not necessary to -- namely 'implementation of XXX operator'. (Note: it's not necessary to
@ -807,7 +807,7 @@ ORDER BY 1;
-- Look for illegal values in pg_aggregate fields. -- Look for illegal values in pg_aggregate fields.
SELECT ctid, aggfnoid::oid SELECT ctid, aggfnoid::oid
FROM pg_aggregate as p1 FROM pg_aggregate as a
WHERE aggfnoid = 0 OR aggtransfn = 0 OR WHERE aggfnoid = 0 OR aggtransfn = 0 OR
aggkind NOT IN ('n', 'o', 'h') OR aggkind NOT IN ('n', 'o', 'h') OR
aggnumdirectargs < 0 OR aggnumdirectargs < 0 OR
@ -893,12 +893,12 @@ WHERE a.aggfnoid = p.oid AND
-- Check for inconsistent specifications of moving-aggregate columns. -- Check for inconsistent specifications of moving-aggregate columns.
SELECT ctid, aggfnoid::oid SELECT ctid, aggfnoid::oid
FROM pg_aggregate as p1 FROM pg_aggregate as a
WHERE aggmtranstype != 0 AND WHERE aggmtranstype != 0 AND
(aggmtransfn = 0 OR aggminvtransfn = 0); (aggmtransfn = 0 OR aggminvtransfn = 0);
SELECT ctid, aggfnoid::oid SELECT ctid, aggfnoid::oid
FROM pg_aggregate as p1 FROM pg_aggregate as a
WHERE aggmtranstype = 0 AND WHERE aggmtranstype = 0 AND
(aggmtransfn != 0 OR aggminvtransfn != 0 OR aggmfinalfn != 0 OR (aggmtransfn != 0 OR aggminvtransfn != 0 OR aggmfinalfn != 0 OR
aggmtransspace != 0 OR aggminitval IS NOT NULL); aggmtransspace != 0 OR aggminitval IS NOT NULL);
@ -1130,9 +1130,9 @@ WHERE prokind = 'a' AND provariadic != 0 AND a.aggkind = 'n';
-- Look for illegal values in pg_opfamily fields -- Look for illegal values in pg_opfamily fields
SELECT p1.oid SELECT f.oid
FROM pg_opfamily as p1 FROM pg_opfamily as f
WHERE p1.opfmethod = 0 OR p1.opfnamespace = 0; WHERE f.opfmethod = 0 OR f.opfnamespace = 0;
-- Look for opfamilies having no opclasses. While most validation of -- Look for opfamilies having no opclasses. While most validation of
-- opfamilies is now handled by AM-specific amvalidate functions, that's -- opfamilies is now handled by AM-specific amvalidate functions, that's
@ -1147,25 +1147,25 @@ WHERE NOT EXISTS (SELECT 1 FROM pg_opclass WHERE opcfamily = f.oid);
-- Look for illegal values in pg_opclass fields -- Look for illegal values in pg_opclass fields
SELECT p1.oid SELECT c1.oid
FROM pg_opclass AS p1 FROM pg_opclass AS c1
WHERE p1.opcmethod = 0 OR p1.opcnamespace = 0 OR p1.opcfamily = 0 WHERE c1.opcmethod = 0 OR c1.opcnamespace = 0 OR c1.opcfamily = 0
OR p1.opcintype = 0; OR c1.opcintype = 0;
-- opcmethod must match owning opfamily's opfmethod -- opcmethod must match owning opfamily's opfmethod
SELECT p1.oid, p2.oid SELECT c1.oid, f1.oid
FROM pg_opclass AS p1, pg_opfamily AS p2 FROM pg_opclass AS c1, pg_opfamily AS f1
WHERE p1.opcfamily = p2.oid AND p1.opcmethod != p2.opfmethod; WHERE c1.opcfamily = f1.oid AND c1.opcmethod != f1.opfmethod;
-- There should not be multiple entries in pg_opclass with opcdefault true -- There should not be multiple entries in pg_opclass with opcdefault true
-- and the same opcmethod/opcintype combination. -- and the same opcmethod/opcintype combination.
SELECT p1.oid, p2.oid SELECT c1.oid, c2.oid
FROM pg_opclass AS p1, pg_opclass AS p2 FROM pg_opclass AS c1, pg_opclass AS c2
WHERE p1.oid != p2.oid AND WHERE c1.oid != c2.oid AND
p1.opcmethod = p2.opcmethod AND p1.opcintype = p2.opcintype AND c1.opcmethod = c2.opcmethod AND c1.opcintype = c2.opcintype AND
p1.opcdefault AND p2.opcdefault; c1.opcdefault AND c2.opcdefault;
-- Ask access methods to validate opclasses -- Ask access methods to validate opclasses
-- (this replaces a lot of SQL-level checks that used to be done in this file) -- (this replaces a lot of SQL-level checks that used to be done in this file)
@ -1177,49 +1177,49 @@ SELECT oid, opcname FROM pg_opclass WHERE NOT amvalidate(oid);
-- Look for illegal values in pg_am fields -- Look for illegal values in pg_am fields
SELECT p1.oid, p1.amname SELECT a1.oid, a1.amname
FROM pg_am AS p1 FROM pg_am AS a1
WHERE p1.amhandler = 0; WHERE a1.amhandler = 0;
-- Check for index amhandler functions with the wrong signature -- Check for index amhandler functions with the wrong signature
SELECT p1.oid, p1.amname, p2.oid, p2.proname SELECT a1.oid, a1.amname, p1.oid, p1.proname
FROM pg_am AS p1, pg_proc AS p2 FROM pg_am AS a1, pg_proc AS p1
WHERE p2.oid = p1.amhandler AND p1.amtype = 'i' AND WHERE p1.oid = a1.amhandler AND a1.amtype = 'i' AND
(p2.prorettype != 'index_am_handler'::regtype (p1.prorettype != 'index_am_handler'::regtype
OR p2.proretset OR p1.proretset
OR p2.pronargs != 1 OR p1.pronargs != 1
OR p2.proargtypes[0] != 'internal'::regtype); OR p1.proargtypes[0] != 'internal'::regtype);
-- Check for table amhandler functions with the wrong signature -- Check for table amhandler functions with the wrong signature
SELECT p1.oid, p1.amname, p2.oid, p2.proname SELECT a1.oid, a1.amname, p1.oid, p1.proname
FROM pg_am AS p1, pg_proc AS p2 FROM pg_am AS a1, pg_proc AS p1
WHERE p2.oid = p1.amhandler AND p1.amtype = 's' AND WHERE p1.oid = a1.amhandler AND a1.amtype = 's' AND
(p2.prorettype != 'table_am_handler'::regtype (p1.prorettype != 'table_am_handler'::regtype
OR p2.proretset OR p1.proretset
OR p2.pronargs != 1 OR p1.pronargs != 1
OR p2.proargtypes[0] != 'internal'::regtype); OR p1.proargtypes[0] != 'internal'::regtype);
-- **************** pg_amop **************** -- **************** pg_amop ****************
-- Look for illegal values in pg_amop fields -- Look for illegal values in pg_amop fields
SELECT p1.amopfamily, p1.amopstrategy SELECT a1.amopfamily, a1.amopstrategy
FROM pg_amop as p1 FROM pg_amop as a1
WHERE p1.amopfamily = 0 OR p1.amoplefttype = 0 OR p1.amoprighttype = 0 WHERE a1.amopfamily = 0 OR a1.amoplefttype = 0 OR a1.amoprighttype = 0
OR p1.amopopr = 0 OR p1.amopmethod = 0 OR p1.amopstrategy < 1; OR a1.amopopr = 0 OR a1.amopmethod = 0 OR a1.amopstrategy < 1;
SELECT p1.amopfamily, p1.amopstrategy SELECT a1.amopfamily, a1.amopstrategy
FROM pg_amop as p1 FROM pg_amop as a1
WHERE NOT ((p1.amoppurpose = 's' AND p1.amopsortfamily = 0) OR WHERE NOT ((a1.amoppurpose = 's' AND a1.amopsortfamily = 0) OR
(p1.amoppurpose = 'o' AND p1.amopsortfamily <> 0)); (a1.amoppurpose = 'o' AND a1.amopsortfamily <> 0));
-- amopmethod must match owning opfamily's opfmethod -- amopmethod must match owning opfamily's opfmethod
SELECT p1.oid, p2.oid SELECT a1.oid, f1.oid
FROM pg_amop AS p1, pg_opfamily AS p2 FROM pg_amop AS a1, pg_opfamily AS f1
WHERE p1.amopfamily = p2.oid AND p1.amopmethod != p2.opfmethod; WHERE a1.amopfamily = f1.oid AND a1.amopmethod != f1.opfmethod;
-- Make a list of all the distinct operator names being used in particular -- Make a list of all the distinct operator names being used in particular
-- strategy slots. This is a bit hokey, since the list might need to change -- strategy slots. This is a bit hokey, since the list might need to change
@ -1227,26 +1227,26 @@ WHERE p1.amopfamily = p2.oid AND p1.amopmethod != p2.opfmethod;
-- swapping two operators within a family. -- swapping two operators within a family.
SELECT DISTINCT amopmethod, amopstrategy, oprname SELECT DISTINCT amopmethod, amopstrategy, oprname
FROM pg_amop p1 LEFT JOIN pg_operator p2 ON amopopr = p2.oid FROM pg_amop a1 LEFT JOIN pg_operator o1 ON amopopr = o1.oid
ORDER BY 1, 2, 3; ORDER BY 1, 2, 3;
-- Check that all opclass search operators have selectivity estimators. -- Check that all opclass search operators have selectivity estimators.
-- This is not absolutely required, but it seems a reasonable thing -- This is not absolutely required, but it seems a reasonable thing
-- to insist on for all standard datatypes. -- to insist on for all standard datatypes.
SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname SELECT a1.amopfamily, a1.amopopr, o1.oid, o1.oprname
FROM pg_amop AS p1, pg_operator AS p2 FROM pg_amop AS a1, pg_operator AS o1
WHERE p1.amopopr = p2.oid AND p1.amoppurpose = 's' AND WHERE a1.amopopr = o1.oid AND a1.amoppurpose = 's' AND
(p2.oprrest = 0 OR p2.oprjoin = 0); (o1.oprrest = 0 OR o1.oprjoin = 0);
-- Check that each opclass in an opfamily has associated operators, that is -- Check that each opclass in an opfamily has associated operators, that is
-- ones whose oprleft matches opcintype (possibly by coercion). -- ones whose oprleft matches opcintype (possibly by coercion).
SELECT p1.opcname, p1.opcfamily SELECT c1.opcname, c1.opcfamily
FROM pg_opclass AS p1 FROM pg_opclass AS c1
WHERE NOT EXISTS(SELECT 1 FROM pg_amop AS p2 WHERE NOT EXISTS(SELECT 1 FROM pg_amop AS a1
WHERE p2.amopfamily = p1.opcfamily WHERE a1.amopfamily = c1.opcfamily
AND binary_coercible(p1.opcintype, p2.amoplefttype)); AND binary_coercible(c1.opcintype, a1.amoplefttype));
-- Check that each operator listed in pg_amop has an associated opclass, -- Check that each operator listed in pg_amop has an associated opclass,
-- that is one whose opcintype matches oprleft (possibly by coercion). -- that is one whose opcintype matches oprleft (possibly by coercion).
@ -1255,55 +1255,55 @@ WHERE NOT EXISTS(SELECT 1 FROM pg_amop AS p2
-- btree opfamilies, but in practice you'd expect there to be an opclass for -- btree opfamilies, but in practice you'd expect there to be an opclass for
-- every datatype the family knows about.) -- every datatype the family knows about.)
SELECT p1.amopfamily, p1.amopstrategy, p1.amopopr SELECT a1.amopfamily, a1.amopstrategy, a1.amopopr
FROM pg_amop AS p1 FROM pg_amop AS a1
WHERE NOT EXISTS(SELECT 1 FROM pg_opclass AS p2 WHERE NOT EXISTS(SELECT 1 FROM pg_opclass AS c1
WHERE p2.opcfamily = p1.amopfamily WHERE c1.opcfamily = a1.amopfamily
AND binary_coercible(p2.opcintype, p1.amoplefttype)); AND binary_coercible(c1.opcintype, a1.amoplefttype));
-- Operators that are primary members of opclasses must be immutable (else -- Operators that are primary members of opclasses must be immutable (else
-- it suggests that the index ordering isn't fixed). Operators that are -- it suggests that the index ordering isn't fixed). Operators that are
-- cross-type members need only be stable, since they are just shorthands -- cross-type members need only be stable, since they are just shorthands
-- for index probe queries. -- for index probe queries.
SELECT p1.amopfamily, p1.amopopr, p2.oprname, p3.prosrc SELECT a1.amopfamily, a1.amopopr, o1.oprname, p1.prosrc
FROM pg_amop AS p1, pg_operator AS p2, pg_proc AS p3 FROM pg_amop AS a1, pg_operator AS o1, pg_proc AS p1
WHERE p1.amopopr = p2.oid AND p2.oprcode = p3.oid AND WHERE a1.amopopr = o1.oid AND o1.oprcode = p1.oid AND
p1.amoplefttype = p1.amoprighttype AND a1.amoplefttype = a1.amoprighttype AND
p3.provolatile != 'i'; p1.provolatile != 'i';
SELECT p1.amopfamily, p1.amopopr, p2.oprname, p3.prosrc SELECT a1.amopfamily, a1.amopopr, o1.oprname, p1.prosrc
FROM pg_amop AS p1, pg_operator AS p2, pg_proc AS p3 FROM pg_amop AS a1, pg_operator AS o1, pg_proc AS p1
WHERE p1.amopopr = p2.oid AND p2.oprcode = p3.oid AND WHERE a1.amopopr = o1.oid AND o1.oprcode = p1.oid AND
p1.amoplefttype != p1.amoprighttype AND a1.amoplefttype != a1.amoprighttype AND
p3.provolatile = 'v'; p1.provolatile = 'v';
-- **************** pg_amproc **************** -- **************** pg_amproc ****************
-- Look for illegal values in pg_amproc fields -- Look for illegal values in pg_amproc fields
SELECT p1.amprocfamily, p1.amprocnum SELECT a1.amprocfamily, a1.amprocnum
FROM pg_amproc as p1 FROM pg_amproc as a1
WHERE p1.amprocfamily = 0 OR p1.amproclefttype = 0 OR p1.amprocrighttype = 0 WHERE a1.amprocfamily = 0 OR a1.amproclefttype = 0 OR a1.amprocrighttype = 0
OR p1.amprocnum < 0 OR p1.amproc = 0; OR a1.amprocnum < 0 OR a1.amproc = 0;
-- Support routines that are primary members of opfamilies must be immutable -- Support routines that are primary members of opfamilies must be immutable
-- (else it suggests that the index ordering isn't fixed). But cross-type -- (else it suggests that the index ordering isn't fixed). But cross-type
-- members need only be stable, since they are just shorthands -- members need only be stable, since they are just shorthands
-- for index probe queries. -- for index probe queries.
SELECT p1.amprocfamily, p1.amproc, p2.prosrc SELECT a1.amprocfamily, a1.amproc, p1.prosrc
FROM pg_amproc AS p1, pg_proc AS p2 FROM pg_amproc AS a1, pg_proc AS p1
WHERE p1.amproc = p2.oid AND WHERE a1.amproc = p1.oid AND
p1.amproclefttype = p1.amprocrighttype AND a1.amproclefttype = a1.amprocrighttype AND
p2.provolatile != 'i'; p1.provolatile != 'i';
SELECT p1.amprocfamily, p1.amproc, p2.prosrc SELECT a1.amprocfamily, a1.amproc, p1.prosrc
FROM pg_amproc AS p1, pg_proc AS p2 FROM pg_amproc AS a1, pg_proc AS p1
WHERE p1.amproc = p2.oid AND WHERE a1.amproc = p1.oid AND
p1.amproclefttype != p1.amprocrighttype AND a1.amproclefttype != a1.amprocrighttype AND
p2.provolatile = 'v'; p1.provolatile = 'v';
-- Almost all of the core distribution's Btree opclasses can use one of the -- Almost all of the core distribution's Btree opclasses can use one of the
-- two generic "equalimage" functions as their support function 4. Look for -- two generic "equalimage" functions as their support function 4. Look for
@ -1328,15 +1328,15 @@ ORDER BY 1, 2, 3;
-- Look for illegal values in pg_index fields. -- Look for illegal values in pg_index fields.
SELECT p1.indexrelid, p1.indrelid SELECT indexrelid, indrelid
FROM pg_index as p1 FROM pg_index
WHERE p1.indexrelid = 0 OR p1.indrelid = 0 OR WHERE indexrelid = 0 OR indrelid = 0 OR
p1.indnatts <= 0 OR p1.indnatts > 32; indnatts <= 0 OR indnatts > 32;
-- oidvector and int2vector fields should be of length indnatts. -- oidvector and int2vector fields should be of length indnatts.
SELECT p1.indexrelid, p1.indrelid SELECT indexrelid, indrelid
FROM pg_index as p1 FROM pg_index
WHERE array_lower(indkey, 1) != 0 OR array_upper(indkey, 1) != indnatts-1 OR WHERE array_lower(indkey, 1) != 0 OR array_upper(indkey, 1) != indnatts-1 OR
array_lower(indclass, 1) != 0 OR array_upper(indclass, 1) != indnatts-1 OR array_lower(indclass, 1) != 0 OR array_upper(indclass, 1) != indnatts-1 OR
array_lower(indcollation, 1) != 0 OR array_upper(indcollation, 1) != indnatts-1 OR array_lower(indcollation, 1) != 0 OR array_upper(indcollation, 1) != indnatts-1 OR

View File

@ -16,94 +16,94 @@
-- Look for illegal values in pg_type fields. -- Look for illegal values in pg_type fields.
SELECT p1.oid, p1.typname SELECT t1.oid, t1.typname
FROM pg_type as p1 FROM pg_type as t1
WHERE p1.typnamespace = 0 OR WHERE t1.typnamespace = 0 OR
(p1.typlen <= 0 AND p1.typlen != -1 AND p1.typlen != -2) OR (t1.typlen <= 0 AND t1.typlen != -1 AND t1.typlen != -2) OR
(p1.typtype not in ('b', 'c', 'd', 'e', 'p', 'r', 'm')) OR (t1.typtype not in ('b', 'c', 'd', 'e', 'p', 'r', 'm')) OR
NOT p1.typisdefined OR NOT t1.typisdefined OR
(p1.typalign not in ('c', 's', 'i', 'd')) OR (t1.typalign not in ('c', 's', 'i', 'd')) OR
(p1.typstorage not in ('p', 'x', 'e', 'm')); (t1.typstorage not in ('p', 'x', 'e', 'm'));
-- Look for "pass by value" types that can't be passed by value. -- Look for "pass by value" types that can't be passed by value.
SELECT p1.oid, p1.typname SELECT t1.oid, t1.typname
FROM pg_type as p1 FROM pg_type as t1
WHERE p1.typbyval AND WHERE t1.typbyval AND
(p1.typlen != 1 OR p1.typalign != 'c') AND (t1.typlen != 1 OR t1.typalign != 'c') AND
(p1.typlen != 2 OR p1.typalign != 's') AND (t1.typlen != 2 OR t1.typalign != 's') AND
(p1.typlen != 4 OR p1.typalign != 'i') AND (t1.typlen != 4 OR t1.typalign != 'i') AND
(p1.typlen != 8 OR p1.typalign != 'd'); (t1.typlen != 8 OR t1.typalign != 'd');
-- Look for "toastable" types that aren't varlena. -- Look for "toastable" types that aren't varlena.
SELECT p1.oid, p1.typname SELECT t1.oid, t1.typname
FROM pg_type as p1 FROM pg_type as t1
WHERE p1.typstorage != 'p' AND WHERE t1.typstorage != 'p' AND
(p1.typbyval OR p1.typlen != -1); (t1.typbyval OR t1.typlen != -1);
-- Look for complex types that do not have a typrelid entry, -- Look for complex types that do not have a typrelid entry,
-- or basic types that do. -- or basic types that do.
SELECT p1.oid, p1.typname SELECT t1.oid, t1.typname
FROM pg_type as p1 FROM pg_type as t1
WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR WHERE (t1.typtype = 'c' AND t1.typrelid = 0) OR
(p1.typtype != 'c' AND p1.typrelid != 0); (t1.typtype != 'c' AND t1.typrelid != 0);
-- Look for types that should have an array type but don't. -- Look for types that should have an array type but don't.
-- Generally anything that's not a pseudotype should have an array type. -- Generally anything that's not a pseudotype should have an array type.
-- However, we do have a small number of exceptions. -- However, we do have a small number of exceptions.
SELECT p1.oid, p1.typname SELECT t1.oid, t1.typname
FROM pg_type as p1 FROM pg_type as t1
WHERE p1.typtype not in ('p') AND p1.typname NOT LIKE E'\\_%' WHERE t1.typtype not in ('p') AND t1.typname NOT LIKE E'\\_%'
AND NOT EXISTS AND NOT EXISTS
(SELECT 1 FROM pg_type as p2 (SELECT 1 FROM pg_type as t2
WHERE p2.typname = ('_' || p1.typname)::name AND WHERE t2.typname = ('_' || t1.typname)::name AND
p2.typelem = p1.oid and p1.typarray = p2.oid) t2.typelem = t1.oid and t1.typarray = t2.oid)
ORDER BY p1.oid; ORDER BY t1.oid;
-- Make sure typarray points to a "true" array type of our own base -- Make sure typarray points to a "true" array type of our own base
SELECT p1.oid, p1.typname as basetype, p2.typname as arraytype, SELECT t1.oid, t1.typname as basetype, t2.typname as arraytype,
p2.typsubscript t2.typsubscript
FROM pg_type p1 LEFT JOIN pg_type p2 ON (p1.typarray = p2.oid) FROM pg_type t1 LEFT JOIN pg_type t2 ON (t1.typarray = t2.oid)
WHERE p1.typarray <> 0 AND WHERE t1.typarray <> 0 AND
(p2.oid IS NULL OR (t2.oid IS NULL OR
p2.typsubscript <> 'array_subscript_handler'::regproc); t2.typsubscript <> 'array_subscript_handler'::regproc);
-- Look for range types that do not have a pg_range entry -- Look for range types that do not have a pg_range entry
SELECT p1.oid, p1.typname SELECT t1.oid, t1.typname
FROM pg_type as p1 FROM pg_type as t1
WHERE p1.typtype = 'r' AND WHERE t1.typtype = 'r' AND
NOT EXISTS(SELECT 1 FROM pg_range r WHERE rngtypid = p1.oid); NOT EXISTS(SELECT 1 FROM pg_range r WHERE rngtypid = t1.oid);
-- Look for range types whose typalign isn't sufficient -- Look for range types whose typalign isn't sufficient
SELECT p1.oid, p1.typname, p1.typalign, p2.typname, p2.typalign SELECT t1.oid, t1.typname, t1.typalign, t2.typname, t2.typalign
FROM pg_type as p1 FROM pg_type as t1
LEFT JOIN pg_range as r ON rngtypid = p1.oid LEFT JOIN pg_range as r ON rngtypid = t1.oid
LEFT JOIN pg_type as p2 ON rngsubtype = p2.oid LEFT JOIN pg_type as t2 ON rngsubtype = t2.oid
WHERE p1.typtype = 'r' AND WHERE t1.typtype = 'r' AND
(p1.typalign != (CASE WHEN p2.typalign = 'd' THEN 'd'::"char" (t1.typalign != (CASE WHEN t2.typalign = 'd' THEN 'd'::"char"
ELSE 'i'::"char" END) ELSE 'i'::"char" END)
OR p2.oid IS NULL); OR t2.oid IS NULL);
-- Text conversion routines must be provided. -- Text conversion routines must be provided.
SELECT p1.oid, p1.typname SELECT t1.oid, t1.typname
FROM pg_type as p1 FROM pg_type as t1
WHERE (p1.typinput = 0 OR p1.typoutput = 0); WHERE (t1.typinput = 0 OR t1.typoutput = 0);
-- Check for bogus typinput routines -- Check for bogus typinput routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typinput = p2.oid AND NOT WHERE t1.typinput = p1.oid AND NOT
((p2.pronargs = 1 AND p2.proargtypes[0] = 'cstring'::regtype) OR ((p1.pronargs = 1 AND p1.proargtypes[0] = 'cstring'::regtype) OR
(p2.pronargs = 2 AND p2.proargtypes[0] = 'cstring'::regtype AND (p1.pronargs = 2 AND p1.proargtypes[0] = 'cstring'::regtype AND
p2.proargtypes[1] = 'oid'::regtype) OR p1.proargtypes[1] = 'oid'::regtype) OR
(p2.pronargs = 3 AND p2.proargtypes[0] = 'cstring'::regtype AND (p1.pronargs = 3 AND p1.proargtypes[0] = 'cstring'::regtype AND
p2.proargtypes[1] = 'oid'::regtype AND p1.proargtypes[1] = 'oid'::regtype AND
p2.proargtypes[2] = 'int4'::regtype)); p1.proargtypes[2] = 'int4'::regtype));
-- Check for type of the variadic array parameter's elements. -- Check for type of the variadic array parameter's elements.
-- provariadic should be ANYOID if the type of the last element is ANYOID, -- provariadic should be ANYOID if the type of the last element is ANYOID,
@ -133,225 +133,225 @@ WHERE (proargmodes IS NOT NULL AND 'v' = any(proargmodes))
-- As of 8.0, this check finds refcursor, which is borrowing -- As of 8.0, this check finds refcursor, which is borrowing
-- other types' I/O routines -- other types' I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND NOT WHERE t1.typinput = p1.oid AND t1.typtype in ('b', 'p') AND NOT
(p1.typelem != 0 AND p1.typlen < 0) AND NOT (t1.typelem != 0 AND t1.typlen < 0) AND NOT
(p2.prorettype = p1.oid AND NOT p2.proretset) (p1.prorettype = t1.oid AND NOT p1.proretset)
ORDER BY 1; ORDER BY 1;
-- Varlena array types will point to array_in -- Varlena array types will point to array_in
-- Exception as of 8.1: int2vector and oidvector have their own I/O routines -- Exception as of 8.1: int2vector and oidvector have their own I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typinput = p2.oid AND WHERE t1.typinput = p1.oid AND
(p1.typelem != 0 AND p1.typlen < 0) AND NOT (t1.typelem != 0 AND t1.typlen < 0) AND NOT
(p2.oid = 'array_in'::regproc) (p1.oid = 'array_in'::regproc)
ORDER BY 1; ORDER BY 1;
-- typinput routines should not be volatile -- typinput routines should not be volatile
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typinput = p2.oid AND p2.provolatile NOT IN ('i', 's'); WHERE t1.typinput = p1.oid AND p1.provolatile NOT IN ('i', 's');
-- Composites, domains, enums, multiranges, ranges should all use the same input routines -- Composites, domains, enums, multiranges, ranges should all use the same input routines
SELECT DISTINCT typtype, typinput SELECT DISTINCT typtype, typinput
FROM pg_type AS p1 FROM pg_type AS t1
WHERE p1.typtype not in ('b', 'p') WHERE t1.typtype not in ('b', 'p')
ORDER BY 1; ORDER BY 1;
-- Check for bogus typoutput routines -- Check for bogus typoutput routines
-- As of 8.0, this check finds refcursor, which is borrowing -- As of 8.0, this check finds refcursor, which is borrowing
-- other types' I/O routines -- other types' I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typoutput = p2.oid AND p1.typtype in ('b', 'p') AND NOT WHERE t1.typoutput = p1.oid AND t1.typtype in ('b', 'p') AND NOT
(p2.pronargs = 1 AND (p1.pronargs = 1 AND
(p2.proargtypes[0] = p1.oid OR (p1.proargtypes[0] = t1.oid OR
(p2.oid = 'array_out'::regproc AND (p1.oid = 'array_out'::regproc AND
p1.typelem != 0 AND p1.typlen = -1))) t1.typelem != 0 AND t1.typlen = -1)))
ORDER BY 1; ORDER BY 1;
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typoutput = p2.oid AND NOT WHERE t1.typoutput = p1.oid AND NOT
(p2.prorettype = 'cstring'::regtype AND NOT p2.proretset); (p1.prorettype = 'cstring'::regtype AND NOT p1.proretset);
-- typoutput routines should not be volatile -- typoutput routines should not be volatile
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typoutput = p2.oid AND p2.provolatile NOT IN ('i', 's'); WHERE t1.typoutput = p1.oid AND p1.provolatile NOT IN ('i', 's');
-- Composites, enums, multiranges, ranges should all use the same output routines -- Composites, enums, multiranges, ranges should all use the same output routines
SELECT DISTINCT typtype, typoutput SELECT DISTINCT typtype, typoutput
FROM pg_type AS p1 FROM pg_type AS t1
WHERE p1.typtype not in ('b', 'd', 'p') WHERE t1.typtype not in ('b', 'd', 'p')
ORDER BY 1; ORDER BY 1;
-- Domains should have same typoutput as their base types -- Domains should have same typoutput as their base types
SELECT p1.oid, p1.typname, p2.oid, p2.typname SELECT t1.oid, t1.typname, t2.oid, t2.typname
FROM pg_type AS p1 LEFT JOIN pg_type AS p2 ON p1.typbasetype = p2.oid FROM pg_type AS t1 LEFT JOIN pg_type AS t2 ON t1.typbasetype = t2.oid
WHERE p1.typtype = 'd' AND p1.typoutput IS DISTINCT FROM p2.typoutput; WHERE t1.typtype = 'd' AND t1.typoutput IS DISTINCT FROM t2.typoutput;
-- Check for bogus typreceive routines -- Check for bogus typreceive routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typreceive = p2.oid AND NOT WHERE t1.typreceive = p1.oid AND NOT
((p2.pronargs = 1 AND p2.proargtypes[0] = 'internal'::regtype) OR ((p1.pronargs = 1 AND p1.proargtypes[0] = 'internal'::regtype) OR
(p2.pronargs = 2 AND p2.proargtypes[0] = 'internal'::regtype AND (p1.pronargs = 2 AND p1.proargtypes[0] = 'internal'::regtype AND
p2.proargtypes[1] = 'oid'::regtype) OR p1.proargtypes[1] = 'oid'::regtype) OR
(p2.pronargs = 3 AND p2.proargtypes[0] = 'internal'::regtype AND (p1.pronargs = 3 AND p1.proargtypes[0] = 'internal'::regtype AND
p2.proargtypes[1] = 'oid'::regtype AND p1.proargtypes[1] = 'oid'::regtype AND
p2.proargtypes[2] = 'int4'::regtype)); p1.proargtypes[2] = 'int4'::regtype));
-- As of 7.4, this check finds refcursor, which is borrowing -- As of 7.4, this check finds refcursor, which is borrowing
-- other types' I/O routines -- other types' I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND NOT WHERE t1.typreceive = p1.oid AND t1.typtype in ('b', 'p') AND NOT
(p1.typelem != 0 AND p1.typlen < 0) AND NOT (t1.typelem != 0 AND t1.typlen < 0) AND NOT
(p2.prorettype = p1.oid AND NOT p2.proretset) (p1.prorettype = t1.oid AND NOT p1.proretset)
ORDER BY 1; ORDER BY 1;
-- Varlena array types will point to array_recv -- Varlena array types will point to array_recv
-- Exception as of 8.1: int2vector and oidvector have their own I/O routines -- Exception as of 8.1: int2vector and oidvector have their own I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typreceive = p2.oid AND WHERE t1.typreceive = p1.oid AND
(p1.typelem != 0 AND p1.typlen < 0) AND NOT (t1.typelem != 0 AND t1.typlen < 0) AND NOT
(p2.oid = 'array_recv'::regproc) (p1.oid = 'array_recv'::regproc)
ORDER BY 1; ORDER BY 1;
-- Suspicious if typreceive doesn't take same number of args as typinput -- Suspicious if typreceive doesn't take same number of args as typinput
SELECT p1.oid, p1.typname, p2.oid, p2.proname, p3.oid, p3.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2, pg_proc AS p3 FROM pg_type AS t1, pg_proc AS p1, pg_proc AS p2
WHERE p1.typinput = p2.oid AND p1.typreceive = p3.oid AND WHERE t1.typinput = p1.oid AND t1.typreceive = p2.oid AND
p2.pronargs != p3.pronargs; p1.pronargs != p2.pronargs;
-- typreceive routines should not be volatile -- typreceive routines should not be volatile
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typreceive = p2.oid AND p2.provolatile NOT IN ('i', 's'); WHERE t1.typreceive = p1.oid AND p1.provolatile NOT IN ('i', 's');
-- Composites, domains, enums, multiranges, ranges should all use the same receive routines -- Composites, domains, enums, multiranges, ranges should all use the same receive routines
SELECT DISTINCT typtype, typreceive SELECT DISTINCT typtype, typreceive
FROM pg_type AS p1 FROM pg_type AS t1
WHERE p1.typtype not in ('b', 'p') WHERE t1.typtype not in ('b', 'p')
ORDER BY 1; ORDER BY 1;
-- Check for bogus typsend routines -- Check for bogus typsend routines
-- As of 7.4, this check finds refcursor, which is borrowing -- As of 7.4, this check finds refcursor, which is borrowing
-- other types' I/O routines -- other types' I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typsend = p2.oid AND p1.typtype in ('b', 'p') AND NOT WHERE t1.typsend = p1.oid AND t1.typtype in ('b', 'p') AND NOT
(p2.pronargs = 1 AND (p1.pronargs = 1 AND
(p2.proargtypes[0] = p1.oid OR (p1.proargtypes[0] = t1.oid OR
(p2.oid = 'array_send'::regproc AND (p1.oid = 'array_send'::regproc AND
p1.typelem != 0 AND p1.typlen = -1))) t1.typelem != 0 AND t1.typlen = -1)))
ORDER BY 1; ORDER BY 1;
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typsend = p2.oid AND NOT WHERE t1.typsend = p1.oid AND NOT
(p2.prorettype = 'bytea'::regtype AND NOT p2.proretset); (p1.prorettype = 'bytea'::regtype AND NOT p1.proretset);
-- typsend routines should not be volatile -- typsend routines should not be volatile
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typsend = p2.oid AND p2.provolatile NOT IN ('i', 's'); WHERE t1.typsend = p1.oid AND p1.provolatile NOT IN ('i', 's');
-- Composites, enums, multiranges, ranges should all use the same send routines -- Composites, enums, multiranges, ranges should all use the same send routines
SELECT DISTINCT typtype, typsend SELECT DISTINCT typtype, typsend
FROM pg_type AS p1 FROM pg_type AS t1
WHERE p1.typtype not in ('b', 'd', 'p') WHERE t1.typtype not in ('b', 'd', 'p')
ORDER BY 1; ORDER BY 1;
-- Domains should have same typsend as their base types -- Domains should have same typsend as their base types
SELECT p1.oid, p1.typname, p2.oid, p2.typname SELECT t1.oid, t1.typname, t2.oid, t2.typname
FROM pg_type AS p1 LEFT JOIN pg_type AS p2 ON p1.typbasetype = p2.oid FROM pg_type AS t1 LEFT JOIN pg_type AS t2 ON t1.typbasetype = t2.oid
WHERE p1.typtype = 'd' AND p1.typsend IS DISTINCT FROM p2.typsend; WHERE t1.typtype = 'd' AND t1.typsend IS DISTINCT FROM t2.typsend;
-- Check for bogus typmodin routines -- Check for bogus typmodin routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typmodin = p2.oid AND NOT WHERE t1.typmodin = p1.oid AND NOT
(p2.pronargs = 1 AND (p1.pronargs = 1 AND
p2.proargtypes[0] = 'cstring[]'::regtype AND p1.proargtypes[0] = 'cstring[]'::regtype AND
p2.prorettype = 'int4'::regtype AND NOT p2.proretset); p1.prorettype = 'int4'::regtype AND NOT p1.proretset);
-- typmodin routines should not be volatile -- typmodin routines should not be volatile
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typmodin = p2.oid AND p2.provolatile NOT IN ('i', 's'); WHERE t1.typmodin = p1.oid AND p1.provolatile NOT IN ('i', 's');
-- Check for bogus typmodout routines -- Check for bogus typmodout routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typmodout = p2.oid AND NOT WHERE t1.typmodout = p1.oid AND NOT
(p2.pronargs = 1 AND (p1.pronargs = 1 AND
p2.proargtypes[0] = 'int4'::regtype AND p1.proargtypes[0] = 'int4'::regtype AND
p2.prorettype = 'cstring'::regtype AND NOT p2.proretset); p1.prorettype = 'cstring'::regtype AND NOT p1.proretset);
-- typmodout routines should not be volatile -- typmodout routines should not be volatile
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typmodout = p2.oid AND p2.provolatile NOT IN ('i', 's'); WHERE t1.typmodout = p1.oid AND p1.provolatile NOT IN ('i', 's');
-- Array types should have same typmodin/out as their element types -- Array types should have same typmodin/out as their element types
SELECT p1.oid, p1.typname, p2.oid, p2.typname SELECT t1.oid, t1.typname, t2.oid, t2.typname
FROM pg_type AS p1, pg_type AS p2 FROM pg_type AS t1, pg_type AS t2
WHERE p1.typelem = p2.oid AND NOT WHERE t1.typelem = t2.oid AND NOT
(p1.typmodin = p2.typmodin AND p1.typmodout = p2.typmodout); (t1.typmodin = t2.typmodin AND t1.typmodout = t2.typmodout);
-- Array types should have same typdelim as their element types -- Array types should have same typdelim as their element types
SELECT p1.oid, p1.typname, p2.oid, p2.typname SELECT t1.oid, t1.typname, t2.oid, t2.typname
FROM pg_type AS p1, pg_type AS p2 FROM pg_type AS t1, pg_type AS t2
WHERE p1.typarray = p2.oid AND NOT (p1.typdelim = p2.typdelim); WHERE t1.typarray = t2.oid AND NOT (t1.typdelim = t2.typdelim);
-- Look for array types whose typalign isn't sufficient -- Look for array types whose typalign isn't sufficient
SELECT p1.oid, p1.typname, p1.typalign, p2.typname, p2.typalign SELECT t1.oid, t1.typname, t1.typalign, t2.typname, t2.typalign
FROM pg_type AS p1, pg_type AS p2 FROM pg_type AS t1, pg_type AS t2
WHERE p1.typarray = p2.oid AND WHERE t1.typarray = t2.oid AND
p2.typalign != (CASE WHEN p1.typalign = 'd' THEN 'd'::"char" t2.typalign != (CASE WHEN t1.typalign = 'd' THEN 'd'::"char"
ELSE 'i'::"char" END); ELSE 'i'::"char" END);
-- Check for typelem set without a handler -- Check for typelem set without a handler
SELECT p1.oid, p1.typname, p1.typelem SELECT t1.oid, t1.typname, t1.typelem
FROM pg_type AS p1 FROM pg_type AS t1
WHERE p1.typelem != 0 AND p1.typsubscript = 0; WHERE t1.typelem != 0 AND t1.typsubscript = 0;
-- Check for misuse of standard subscript handlers -- Check for misuse of standard subscript handlers
SELECT p1.oid, p1.typname, SELECT t1.oid, t1.typname,
p1.typelem, p1.typlen, p1.typbyval t1.typelem, t1.typlen, t1.typbyval
FROM pg_type AS p1 FROM pg_type AS t1
WHERE p1.typsubscript = 'array_subscript_handler'::regproc AND NOT WHERE t1.typsubscript = 'array_subscript_handler'::regproc AND NOT
(p1.typelem != 0 AND p1.typlen = -1 AND NOT p1.typbyval); (t1.typelem != 0 AND t1.typlen = -1 AND NOT t1.typbyval);
SELECT p1.oid, p1.typname, SELECT t1.oid, t1.typname,
p1.typelem, p1.typlen, p1.typbyval t1.typelem, t1.typlen, t1.typbyval
FROM pg_type AS p1 FROM pg_type AS t1
WHERE p1.typsubscript = 'raw_array_subscript_handler'::regproc AND NOT WHERE t1.typsubscript = 'raw_array_subscript_handler'::regproc AND NOT
(p1.typelem != 0 AND p1.typlen > 0 AND NOT p1.typbyval); (t1.typelem != 0 AND t1.typlen > 0 AND NOT t1.typbyval);
-- Check for bogus typanalyze routines -- Check for bogus typanalyze routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS t1, pg_proc AS p1
WHERE p1.typanalyze = p2.oid AND NOT WHERE t1.typanalyze = p1.oid AND NOT
(p2.pronargs = 1 AND (p1.pronargs = 1 AND
p2.proargtypes[0] = 'internal'::regtype AND p1.proargtypes[0] = 'internal'::regtype AND
p2.prorettype = 'bool'::regtype AND NOT p2.proretset); p1.prorettype = 'bool'::regtype AND NOT p1.proretset);
-- there does not seem to be a reason to care about volatility of typanalyze -- there does not seem to be a reason to care about volatility of typanalyze
@ -384,23 +384,23 @@ ORDER BY 1;
-- Look for illegal values in pg_class fields -- Look for illegal values in pg_class fields
SELECT p1.oid, p1.relname SELECT c1.oid, c1.relname
FROM pg_class as p1 FROM pg_class as c1
WHERE relkind NOT IN ('r', 'i', 'S', 't', 'v', 'm', 'c', 'f', 'p') OR WHERE relkind NOT IN ('r', 'i', 'S', 't', 'v', 'm', 'c', 'f', 'p') OR
relpersistence NOT IN ('p', 'u', 't') OR relpersistence NOT IN ('p', 'u', 't') OR
relreplident NOT IN ('d', 'n', 'f', 'i'); relreplident NOT IN ('d', 'n', 'f', 'i');
-- All tables and indexes should have an access method. -- All tables and indexes should have an access method.
SELECT p1.oid, p1.relname SELECT c1.oid, c1.relname
FROM pg_class as p1 FROM pg_class as c1
WHERE p1.relkind NOT IN ('S', 'v', 'f', 'c') and WHERE c1.relkind NOT IN ('S', 'v', 'f', 'c') and
p1.relam = 0; c1.relam = 0;
-- Conversely, sequences, views, types shouldn't have them -- Conversely, sequences, views, types shouldn't have them
SELECT p1.oid, p1.relname SELECT c1.oid, c1.relname
FROM pg_class as p1 FROM pg_class as c1
WHERE p1.relkind IN ('S', 'v', 'f', 'c') and WHERE c1.relkind IN ('S', 'v', 'f', 'c') and
p1.relam != 0; c1.relam != 0;
-- Indexes should have AMs of type 'i' -- Indexes should have AMs of type 'i'
SELECT pc.oid, pc.relname, pa.amname, pa.amtype SELECT pc.oid, pc.relname, pa.amname, pa.amtype
@ -418,83 +418,83 @@ WHERE pc.relkind IN ('r', 't', 'm') and
-- Look for illegal values in pg_attribute fields -- Look for illegal values in pg_attribute fields
SELECT p1.attrelid, p1.attname SELECT a1.attrelid, a1.attname
FROM pg_attribute as p1 FROM pg_attribute as a1
WHERE p1.attrelid = 0 OR p1.atttypid = 0 OR p1.attnum = 0 OR WHERE a1.attrelid = 0 OR a1.atttypid = 0 OR a1.attnum = 0 OR
p1.attcacheoff != -1 OR p1.attinhcount < 0 OR a1.attcacheoff != -1 OR a1.attinhcount < 0 OR
(p1.attinhcount = 0 AND NOT p1.attislocal); (a1.attinhcount = 0 AND NOT a1.attislocal);
-- Cross-check attnum against parent relation -- Cross-check attnum against parent relation
SELECT p1.attrelid, p1.attname, p2.oid, p2.relname SELECT a1.attrelid, a1.attname, c1.oid, c1.relname
FROM pg_attribute AS p1, pg_class AS p2 FROM pg_attribute AS a1, pg_class AS c1
WHERE p1.attrelid = p2.oid AND p1.attnum > p2.relnatts; WHERE a1.attrelid = c1.oid AND a1.attnum > c1.relnatts;
-- Detect missing pg_attribute entries: should have as many non-system -- Detect missing pg_attribute entries: should have as many non-system
-- attributes as parent relation expects -- attributes as parent relation expects
SELECT p1.oid, p1.relname SELECT c1.oid, c1.relname
FROM pg_class AS p1 FROM pg_class AS c1
WHERE p1.relnatts != (SELECT count(*) FROM pg_attribute AS p2 WHERE c1.relnatts != (SELECT count(*) FROM pg_attribute AS a1
WHERE p2.attrelid = p1.oid AND p2.attnum > 0); WHERE a1.attrelid = c1.oid AND a1.attnum > 0);
-- Cross-check against pg_type entry -- Cross-check against pg_type entry
-- NOTE: we allow attstorage to be 'plain' even when typstorage is not; -- NOTE: we allow attstorage to be 'plain' even when typstorage is not;
-- this is mainly for toast tables. -- this is mainly for toast tables.
SELECT p1.attrelid, p1.attname, p2.oid, p2.typname SELECT a1.attrelid, a1.attname, t1.oid, t1.typname
FROM pg_attribute AS p1, pg_type AS p2 FROM pg_attribute AS a1, pg_type AS t1
WHERE p1.atttypid = p2.oid AND WHERE a1.atttypid = t1.oid AND
(p1.attlen != p2.typlen OR (a1.attlen != t1.typlen OR
p1.attalign != p2.typalign OR a1.attalign != t1.typalign OR
p1.attbyval != p2.typbyval OR a1.attbyval != t1.typbyval OR
(p1.attstorage != p2.typstorage AND p1.attstorage != 'p')); (a1.attstorage != t1.typstorage AND a1.attstorage != 'p'));
-- **************** pg_range **************** -- **************** pg_range ****************
-- Look for illegal values in pg_range fields. -- Look for illegal values in pg_range fields.
SELECT p1.rngtypid, p1.rngsubtype SELECT r.rngtypid, r.rngsubtype
FROM pg_range as p1 FROM pg_range as r
WHERE p1.rngtypid = 0 OR p1.rngsubtype = 0 OR p1.rngsubopc = 0; WHERE r.rngtypid = 0 OR r.rngsubtype = 0 OR r.rngsubopc = 0;
-- rngcollation should be specified iff subtype is collatable -- rngcollation should be specified iff subtype is collatable
SELECT p1.rngtypid, p1.rngsubtype, p1.rngcollation, t.typcollation SELECT r.rngtypid, r.rngsubtype, r.rngcollation, t.typcollation
FROM pg_range p1 JOIN pg_type t ON t.oid = p1.rngsubtype FROM pg_range r JOIN pg_type t ON t.oid = r.rngsubtype
WHERE (rngcollation = 0) != (typcollation = 0); WHERE (rngcollation = 0) != (typcollation = 0);
-- opclass had better be a btree opclass accepting the subtype. -- opclass had better be a btree opclass accepting the subtype.
-- We must allow anyarray matches, cf IsBinaryCoercible() -- We must allow anyarray matches, cf IsBinaryCoercible()
SELECT p1.rngtypid, p1.rngsubtype, o.opcmethod, o.opcname SELECT r.rngtypid, r.rngsubtype, o.opcmethod, o.opcname
FROM pg_range p1 JOIN pg_opclass o ON o.oid = p1.rngsubopc FROM pg_range r JOIN pg_opclass o ON o.oid = r.rngsubopc
WHERE o.opcmethod != 403 OR WHERE o.opcmethod != 403 OR
((o.opcintype != p1.rngsubtype) AND NOT ((o.opcintype != r.rngsubtype) AND NOT
(o.opcintype = 'pg_catalog.anyarray'::regtype AND (o.opcintype = 'pg_catalog.anyarray'::regtype AND
EXISTS(select 1 from pg_catalog.pg_type where EXISTS(select 1 from pg_catalog.pg_type where
oid = p1.rngsubtype and typelem != 0 and oid = r.rngsubtype and typelem != 0 and
typsubscript = 'array_subscript_handler'::regproc))); typsubscript = 'array_subscript_handler'::regproc)));
-- canonical function, if any, had better match the range type -- canonical function, if any, had better match the range type
SELECT p1.rngtypid, p1.rngsubtype, p.proname SELECT r.rngtypid, r.rngsubtype, p.proname
FROM pg_range p1 JOIN pg_proc p ON p.oid = p1.rngcanonical FROM pg_range r JOIN pg_proc p ON p.oid = r.rngcanonical
WHERE pronargs != 1 OR proargtypes[0] != rngtypid OR prorettype != rngtypid; WHERE pronargs != 1 OR proargtypes[0] != rngtypid OR prorettype != rngtypid;
-- subdiff function, if any, had better match the subtype -- subdiff function, if any, had better match the subtype
SELECT p1.rngtypid, p1.rngsubtype, p.proname SELECT r.rngtypid, r.rngsubtype, p.proname
FROM pg_range p1 JOIN pg_proc p ON p.oid = p1.rngsubdiff FROM pg_range r JOIN pg_proc p ON p.oid = r.rngsubdiff
WHERE pronargs != 2 WHERE pronargs != 2
OR proargtypes[0] != rngsubtype OR proargtypes[1] != rngsubtype OR proargtypes[0] != rngsubtype OR proargtypes[1] != rngsubtype
OR prorettype != 'pg_catalog.float8'::regtype; OR prorettype != 'pg_catalog.float8'::regtype;
-- every range should have a valid multirange -- every range should have a valid multirange
SELECT p1.rngtypid, p1.rngsubtype, p1.rngmultitypid SELECT r.rngtypid, r.rngsubtype, r.rngmultitypid
FROM pg_range p1 FROM pg_range r
WHERE p1.rngmultitypid IS NULL OR p1.rngmultitypid = 0; WHERE r.rngmultitypid IS NULL OR r.rngmultitypid = 0;
-- Create a table that holds all the known in-core data types and leave it -- Create a table that holds all the known in-core data types and leave it
-- around so as pg_upgrade is able to test their binary compatibility. -- around so as pg_upgrade is able to test their binary compatibility.