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:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'));
|
||||
|
||||
Reference in New Issue
Block a user