1
0
mirror of https://github.com/postgres/postgres.git synced 2025-12-07 12:02:30 +03:00

Implement types regprocedure, regoper, regoperator, regclass, regtype

per pghackers discussion.  Add some more typsanity tests, and clean
up some problems exposed thereby (broken or missing array types for
some built-in types).  Also, clean up loose ends from unknownin/out
patch.
This commit is contained in:
Tom Lane
2002-04-25 02:56:56 +00:00
parent 4eac3919dd
commit 52200befd0
28 changed files with 1638 additions and 229 deletions

View File

@@ -14,11 +14,6 @@
--
-- NB: run this test earlier than the create_operator test, because
-- that test creates some bogus operators...
--
-- NOTE hardwired assumptions about standard types:
-- type bool has OID 16
-- type float8 has OID 701
--
-- **************** pg_proc ****************
-- Look for illegal values in pg_proc fields.
-- NOTE: currently there are a few pg_proc entries that have prorettype = 0.
@@ -26,7 +21,7 @@
SELECT p1.oid, p1.proname
FROM pg_proc as p1
WHERE (p1.prolang = 0 OR p1.prorettype = 0 OR
p1.pronargs < 0 OR p1.pronargs > 9)
p1.pronargs < 0 OR p1.pronargs > 16)
AND p1.proname !~ '^pl[^_]+_call_handler$'
AND p1.proname !~ '^RI_FKey_'
AND p1.proname !~ 'costestimate$'
@@ -196,7 +191,7 @@ WHERE p1.proimplicit AND
t.typname = p1.proname) OR
NOT ((p1.pronargs = 1 AND p1.proargtypes[0] != prorettype) OR
(p1.pronargs = 2 AND p1.proargtypes[0] = prorettype AND
p1.proargtypes[1] = 23)));
p1.proargtypes[1] = 'int4'::regtype)));
oid | proname
-----+---------
(0 rows)
@@ -263,8 +258,8 @@ WHERE p1.oprnegate = p2.oid AND
(p1.oprkind != p2.oprkind OR
p1.oprleft != p2.oprleft OR
p1.oprright != p2.oprright OR
p1.oprresult != 16 OR
p2.oprresult != 16 OR
p1.oprresult != 'bool'::regtype OR
p2.oprresult != 'bool'::regtype OR
p1.oid != p2.oprnegate OR
p1.oid = p2.oid);
oid | oprcode | oid | oprcode
@@ -282,8 +277,8 @@ WHERE p1.oprlsortop = p2.oid AND
p1.oprkind != 'b' OR p2.oprkind != 'b' OR
p1.oprleft != p2.oprleft OR
p1.oprleft != p2.oprright OR
p1.oprresult != 16 OR
p2.oprresult != 16 OR
p1.oprresult != 'bool'::regtype OR
p2.oprresult != 'bool'::regtype OR
p1.oprrsortop = 0);
oid | oprcode | oid | oprcode
-----+---------+-----+---------
@@ -296,8 +291,8 @@ WHERE p1.oprrsortop = p2.oid AND
p1.oprkind != 'b' OR p2.oprkind != 'b' OR
p1.oprright != p2.oprleft OR
p1.oprright != p2.oprright OR
p1.oprresult != 16 OR
p2.oprresult != 16 OR
p1.oprresult != 'bool'::regtype OR
p2.oprresult != 'bool'::regtype OR
p1.oprlsortop = 0);
oid | oprcode | oid | oprcode
-----+---------+-----+---------
@@ -363,8 +358,8 @@ WHERE p1.oprlsortop != p1.oprrsortop AND
SELECT p1.oid, p1.oprname
FROM pg_operator AS p1
WHERE p1.oprcanhash AND NOT
(p1.oprkind = 'b' AND p1.oprresult = 16 AND p1.oprleft = p1.oprright AND
p1.oprname = '=' AND p1.oprcom = p1.oid);
(p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND
p1.oprleft = p1.oprright AND p1.oprname = '=' AND p1.oprcom = p1.oid);
oid | oprname
------+---------
353 | =
@@ -448,11 +443,11 @@ WHERE p1.oprcode = p2.oid AND
SELECT p1.oid, p1.oprname, p2.oid, p2.proname
FROM pg_operator AS p1, pg_proc AS p2
WHERE p1.oprrest = p2.oid AND
(p1.oprresult != 16 OR
p2.prorettype != 701 OR p2.proretset OR
(p1.oprresult != 'bool'::regtype OR
p2.prorettype != 'float8'::regtype OR p2.proretset OR
p2.pronargs != 4 OR
p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 26 OR
p2.proargtypes[2] != 0 OR p2.proargtypes[3] != 23);
p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 'oid'::regtype OR
p2.proargtypes[2] != 0 OR p2.proargtypes[3] != 'int4'::regtype);
oid | oprname | oid | proname
-----+---------+-----+---------
(0 rows)
@@ -464,10 +459,10 @@ WHERE p1.oprrest = p2.oid AND
SELECT p1.oid, p1.oprname, p2.oid, p2.proname
FROM pg_operator AS p1, pg_proc AS p2
WHERE p1.oprjoin = p2.oid AND
(p1.oprkind != 'b' OR p1.oprresult != 16 OR
p2.prorettype != 701 OR p2.proretset OR
(p1.oprkind != 'b' OR p1.oprresult != 'bool'::regtype OR
p2.prorettype != 'float8'::regtype OR p2.proretset OR
p2.pronargs != 3 OR
p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 26 OR
p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 'oid'::regtype OR
p2.proargtypes[2] != 0);
oid | oprname | oid | proname
-----+---------+-----+---------
@@ -611,7 +606,8 @@ WHERE p2.opcamid = p1.oid AND
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname
FROM pg_amop AS p1, pg_operator AS p2
WHERE p1.amopopr = p2.oid AND
(p2.oprkind != 'b' OR p2.oprresult != 16 OR p2.oprleft != p2.oprright);
(p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype OR
p2.oprleft != p2.oprright);
amopclaid | amopopr | oid | oprname
-----------+---------+-----+---------
(0 rows)

View File

@@ -19,7 +19,9 @@ WHERE (p1.typlen <= 0 AND p1.typlen != -1) OR
(p1.typtype != 'b' AND p1.typtype != 'c') OR
NOT p1.typisdefined OR
(p1.typalign != 'c' AND p1.typalign != 's' AND
p1.typalign != 'i' AND p1.typalign != 'd');
p1.typalign != 'i' AND p1.typalign != 'd') OR
(p1.typstorage != 'p' AND p1.typstorage != 'x' AND
p1.typstorage != 'e' AND p1.typstorage != 'm');
oid | typname
-----+---------
(0 rows)
@@ -35,6 +37,15 @@ WHERE p1.typbyval AND
-----+---------
(0 rows)
-- Look for "toastable" types that aren't varlena.
SELECT p1.oid, p1.typname
FROM pg_type as p1
WHERE p1.typstorage != 'p' AND
(p1.typbyval OR p1.typlen != -1);
oid | typname
-----+---------
(0 rows)
-- Look for complex types that do not have a typrelid entry,
-- or basic types that do.
SELECT p1.oid, p1.typname
@@ -45,6 +56,31 @@ WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR
-----+---------
(0 rows)
-- Look for basic types that don't have an array type.
-- NOTE: as of 7.3, this check finds SET, smgr, and unknown.
SELECT p1.oid, p1.typname
FROM pg_type as p1
WHERE p1.typtype != 'c' AND p1.typname NOT LIKE '\\_%' AND NOT EXISTS
(SELECT 1 FROM pg_type as p2
WHERE p2.typname = ('_' || p1.typname)::name AND
p2.typelem = p1.oid);
oid | typname
-----+---------
32 | SET
210 | smgr
705 | unknown
(3 rows)
-- Look for array types that don't have an equality operator.
SELECT p1.oid, p1.typname
FROM pg_type as p1
WHERE p1.typtype != 'c' AND p1.typname LIKE '\\_%' AND NOT EXISTS
(SELECT 1 FROM pg_operator
WHERE oprname = '=' AND oprleft = p1.oid AND oprright = p1.oid);
oid | typname
-----+---------
(0 rows)
-- Conversion routines must be provided except in 'c' entries.
SELECT p1.oid, p1.typname
FROM pg_type as p1
@@ -63,7 +99,7 @@ SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typinput = p2.oid AND p1.typtype = 'b' AND
(p2.pronargs != 1 OR p2.proretset) AND
(p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 23);
(p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 'int4'::regtype);
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
@@ -89,7 +125,7 @@ SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typreceive = p2.oid AND p1.typtype = 'b' AND
(p2.pronargs != 1 OR p2.proretset) AND
(p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 23);
(p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 'int4'::regtype);
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
@@ -154,12 +190,15 @@ WHERE p1.relnatts != (SELECT count(*) FROM pg_attribute AS p2
(0 rows)
-- Cross-check against pg_type entry
-- NOTE: we allow attstorage to be 'plain' even when typstorage is not;
-- this is mainly for toast tables.
SELECT p1.attrelid, p1.attname, p2.oid, p2.typname
FROM pg_attribute AS p1, pg_type AS p2
WHERE p1.atttypid = p2.oid AND
(p1.attlen != p2.typlen OR
p1.attalign != p2.typalign OR
p1.attbyval != p2.typbyval);
p1.attbyval != p2.typbyval OR
(p1.attstorage != p2.typstorage AND p1.attstorage != 'p'));
attrelid | attname | oid | typname
----------+---------+-----+---------
(0 rows)

View File

@@ -14,11 +14,6 @@
--
-- NB: run this test earlier than the create_operator test, because
-- that test creates some bogus operators...
--
-- NOTE hardwired assumptions about standard types:
-- type bool has OID 16
-- type float8 has OID 701
--
-- **************** pg_proc ****************
@@ -29,7 +24,7 @@
SELECT p1.oid, p1.proname
FROM pg_proc as p1
WHERE (p1.prolang = 0 OR p1.prorettype = 0 OR
p1.pronargs < 0 OR p1.pronargs > 9)
p1.pronargs < 0 OR p1.pronargs > 16)
AND p1.proname !~ '^pl[^_]+_call_handler$'
AND p1.proname !~ '^RI_FKey_'
AND p1.proname !~ 'costestimate$'
@@ -158,7 +153,7 @@ WHERE p1.proimplicit AND
t.typname = p1.proname) OR
NOT ((p1.pronargs = 1 AND p1.proargtypes[0] != prorettype) OR
(p1.pronargs = 2 AND p1.proargtypes[0] = prorettype AND
p1.proargtypes[1] = 23)));
p1.proargtypes[1] = 'int4'::regtype)));
-- **************** pg_operator ****************
@@ -216,8 +211,8 @@ WHERE p1.oprnegate = p2.oid AND
(p1.oprkind != p2.oprkind OR
p1.oprleft != p2.oprleft OR
p1.oprright != p2.oprright OR
p1.oprresult != 16 OR
p2.oprresult != 16 OR
p1.oprresult != 'bool'::regtype OR
p2.oprresult != 'bool'::regtype OR
p1.oid != p2.oprnegate OR
p1.oid = p2.oid);
@@ -233,8 +228,8 @@ WHERE p1.oprlsortop = p2.oid AND
p1.oprkind != 'b' OR p2.oprkind != 'b' OR
p1.oprleft != p2.oprleft OR
p1.oprleft != p2.oprright OR
p1.oprresult != 16 OR
p2.oprresult != 16 OR
p1.oprresult != 'bool'::regtype OR
p2.oprresult != 'bool'::regtype OR
p1.oprrsortop = 0);
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
@@ -244,8 +239,8 @@ WHERE p1.oprrsortop = p2.oid AND
p1.oprkind != 'b' OR p2.oprkind != 'b' OR
p1.oprright != p2.oprleft OR
p1.oprright != p2.oprright OR
p1.oprresult != 16 OR
p2.oprresult != 16 OR
p1.oprresult != 'bool'::regtype OR
p2.oprresult != 'bool'::regtype OR
p1.oprlsortop = 0);
-- A mergejoinable = operator must have a commutator (usually itself)
@@ -300,8 +295,8 @@ WHERE p1.oprlsortop != p1.oprrsortop AND
SELECT p1.oid, p1.oprname
FROM pg_operator AS p1
WHERE p1.oprcanhash AND NOT
(p1.oprkind = 'b' AND p1.oprresult = 16 AND p1.oprleft = p1.oprright AND
p1.oprname = '=' AND p1.oprcom = p1.oid);
(p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND
p1.oprleft = p1.oprright AND p1.oprname = '=' AND p1.oprcom = p1.oid);
-- In 6.5 we accepted hashable array equality operators when the array element
-- type is hashable. However, what we actually need to make hashjoin work on
@@ -372,11 +367,11 @@ WHERE p1.oprcode = p2.oid AND
SELECT p1.oid, p1.oprname, p2.oid, p2.proname
FROM pg_operator AS p1, pg_proc AS p2
WHERE p1.oprrest = p2.oid AND
(p1.oprresult != 16 OR
p2.prorettype != 701 OR p2.proretset OR
(p1.oprresult != 'bool'::regtype OR
p2.prorettype != 'float8'::regtype OR p2.proretset OR
p2.pronargs != 4 OR
p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 26 OR
p2.proargtypes[2] != 0 OR p2.proargtypes[3] != 23);
p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 'oid'::regtype OR
p2.proargtypes[2] != 0 OR p2.proargtypes[3] != 'int4'::regtype);
-- If oprjoin is set, the operator must be a binary boolean op,
-- and it must link to a proc with the right signature
@@ -386,10 +381,10 @@ WHERE p1.oprrest = p2.oid AND
SELECT p1.oid, p1.oprname, p2.oid, p2.proname
FROM pg_operator AS p1, pg_proc AS p2
WHERE p1.oprjoin = p2.oid AND
(p1.oprkind != 'b' OR p1.oprresult != 16 OR
p2.prorettype != 701 OR p2.proretset OR
(p1.oprkind != 'b' OR p1.oprresult != 'bool'::regtype OR
p2.prorettype != 'float8'::regtype OR p2.proretset OR
p2.pronargs != 3 OR
p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 26 OR
p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 'oid'::regtype OR
p2.proargtypes[2] != 0);
-- **************** pg_aggregate ****************
@@ -507,7 +502,8 @@ WHERE p2.opcamid = p1.oid AND
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname
FROM pg_amop AS p1, pg_operator AS p2
WHERE p1.amopopr = p2.oid AND
(p2.oprkind != 'b' OR p2.oprresult != 16 OR p2.oprleft != p2.oprright);
(p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype OR
p2.oprleft != p2.oprright);
-- Check that all operators linked to by opclass entries have selectivity
-- estimators. This is not absolutely required, but it seems a reasonable

View File

@@ -22,7 +22,9 @@ WHERE (p1.typlen <= 0 AND p1.typlen != -1) OR
(p1.typtype != 'b' AND p1.typtype != 'c') OR
NOT p1.typisdefined OR
(p1.typalign != 'c' AND p1.typalign != 's' AND
p1.typalign != 'i' AND p1.typalign != 'd');
p1.typalign != 'i' AND p1.typalign != 'd') OR
(p1.typstorage != 'p' AND p1.typstorage != 'x' AND
p1.typstorage != 'e' AND p1.typstorage != 'm');
-- Look for "pass by value" types that can't be passed by value.
@@ -33,6 +35,13 @@ WHERE p1.typbyval AND
(p1.typlen != 2 OR p1.typalign != 's') AND
(p1.typlen != 4 OR p1.typalign != 'i');
-- Look for "toastable" types that aren't varlena.
SELECT p1.oid, p1.typname
FROM pg_type as p1
WHERE p1.typstorage != 'p' AND
(p1.typbyval OR p1.typlen != -1);
-- Look for complex types that do not have a typrelid entry,
-- or basic types that do.
@@ -41,6 +50,24 @@ FROM pg_type as p1
WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR
(p1.typtype != 'c' AND p1.typrelid != 0);
-- Look for basic types that don't have an array type.
-- NOTE: as of 7.3, this check finds SET, smgr, and unknown.
SELECT p1.oid, p1.typname
FROM pg_type as p1
WHERE p1.typtype != 'c' AND p1.typname NOT LIKE '\\_%' AND NOT EXISTS
(SELECT 1 FROM pg_type as p2
WHERE p2.typname = ('_' || p1.typname)::name AND
p2.typelem = p1.oid);
-- Look for array types that don't have an equality operator.
SELECT p1.oid, p1.typname
FROM pg_type as p1
WHERE p1.typtype != 'c' AND p1.typname LIKE '\\_%' AND NOT EXISTS
(SELECT 1 FROM pg_operator
WHERE oprname = '=' AND oprleft = p1.oid AND oprright = p1.oid);
-- Conversion routines must be provided except in 'c' entries.
SELECT p1.oid, p1.typname
@@ -58,7 +85,7 @@ SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typinput = p2.oid AND p1.typtype = 'b' AND
(p2.pronargs != 1 OR p2.proretset) AND
(p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 23);
(p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 'int4'::regtype);
-- Check for bogus typoutput routines
-- The first OR subclause detects bogus non-array cases,
@@ -80,7 +107,7 @@ SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typreceive = p2.oid AND p1.typtype = 'b' AND
(p2.pronargs != 1 OR p2.proretset) AND
(p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 23);
(p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 'int4'::regtype);
-- Check for bogus typsend routines
-- The first OR subclause detects bogus non-array cases,
@@ -132,10 +159,13 @@ WHERE p1.relnatts != (SELECT count(*) FROM pg_attribute AS p2
WHERE p2.attrelid = p1.oid AND p2.attnum > 0);
-- Cross-check against pg_type entry
-- NOTE: we allow attstorage to be 'plain' even when typstorage is not;
-- this is mainly for toast tables.
SELECT p1.attrelid, p1.attname, p2.oid, p2.typname
FROM pg_attribute AS p1, pg_type AS p2
WHERE p1.atttypid = p2.oid AND
(p1.attlen != p2.typlen OR
p1.attalign != p2.typalign OR
p1.attbyval != p2.typbyval);
p1.attbyval != p2.typbyval OR
(p1.attstorage != p2.typstorage AND p1.attstorage != 'p'));