mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Further review of range-types patch.
Lots of documentation cleanup today, and still more type_sanity tests.
This commit is contained in:
@ -2986,7 +2986,8 @@ getTypes(int *numTypes)
|
||||
/*
|
||||
* If it's a base type, make a DumpableObject representing a shell
|
||||
* definition of the type. We will need to dump that ahead of the I/O
|
||||
* functions for the type.
|
||||
* functions for the type. Similarly, range types need a shell
|
||||
* definition in case they have a canonicalize function.
|
||||
*
|
||||
* Note: the shell type doesn't have a catId. You might think it
|
||||
* should copy the base type's catId, but then it might capture the
|
||||
@ -3006,8 +3007,8 @@ getTypes(int *numTypes)
|
||||
|
||||
/*
|
||||
* Initially mark the shell type as not to be dumped. We'll only
|
||||
* dump it if the I/O functions need to be dumped; this is taken
|
||||
* care of while sorting dependencies.
|
||||
* dump it if the I/O or canonicalize functions need to be dumped;
|
||||
* this is taken care of while sorting dependencies.
|
||||
*/
|
||||
stinfo->dobj.dump = false;
|
||||
|
||||
@ -7340,6 +7341,9 @@ dumpType(Archive *fout, TypeInfo *tyinfo)
|
||||
dumpEnumType(fout, tyinfo);
|
||||
else if (tyinfo->typtype == TYPTYPE_RANGE)
|
||||
dumpRangeType(fout, tyinfo);
|
||||
else
|
||||
write_msg(NULL, "WARNING: typtype of data type \"%s\" appears to be invalid\n",
|
||||
tyinfo->dobj.name);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -636,7 +636,8 @@ findLoop(DumpableObject *obj,
|
||||
/*
|
||||
* A user-defined datatype will have a dependency loop with each of its
|
||||
* I/O functions (since those have the datatype as input or output).
|
||||
* Break the loop and make the I/O function depend on the associated
|
||||
* Similarly, a range type will have a loop with its canonicalize function,
|
||||
* if any. Break the loop by making the function depend on the associated
|
||||
* shell type, instead.
|
||||
*/
|
||||
static void
|
||||
@ -651,7 +652,7 @@ repairTypeFuncLoop(DumpableObject *typeobj, DumpableObject *funcobj)
|
||||
if (typeInfo->shellType)
|
||||
{
|
||||
addObjectDependency(funcobj, typeInfo->shellType->dobj.dumpId);
|
||||
/* Mark shell type as to be dumped if any I/O function is */
|
||||
/* Mark shell type as to be dumped if any such function is */
|
||||
if (funcobj->dump)
|
||||
typeInfo->shellType->dobj.dump = true;
|
||||
}
|
||||
@ -789,7 +790,7 @@ repairDependencyLoop(DumpableObject **loop,
|
||||
int i,
|
||||
j;
|
||||
|
||||
/* Datatype and one of its I/O functions */
|
||||
/* Datatype and one of its I/O or canonicalize functions */
|
||||
if (nLoop == 2 &&
|
||||
loop[0]->objType == DO_TYPE &&
|
||||
loop[1]->objType == DO_FUNC)
|
||||
|
@ -34,7 +34,7 @@
|
||||
CATALOG(pg_range,3541) BKI_WITHOUT_OIDS
|
||||
{
|
||||
Oid rngtypid; /* OID of owning range type */
|
||||
Oid rngsubtype; /* OID of range's subtype */
|
||||
Oid rngsubtype; /* OID of range's element type (subtype) */
|
||||
Oid rngcollation; /* collation for this range type, or 0 */
|
||||
Oid rngsubopc; /* subtype's btree opclass */
|
||||
regproc rngcanonical; /* canonicalize range, or 0 */
|
||||
|
@ -61,8 +61,9 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71) BKI_SCHEMA_MACRO
|
||||
|
||||
/*
|
||||
* typtype is 'b' for a base type, 'c' for a composite type (e.g., a
|
||||
* table's rowtype), 'd' for a domain type, 'e' for an enum type, or 'p'
|
||||
* for a pseudo-type. (Use the TYPTYPE macros below.)
|
||||
* table's rowtype), 'd' for a domain, 'e' for an enum type,
|
||||
* 'p' for a pseudo-type, or 'r' for a range type.
|
||||
* (Use the TYPTYPE macros below.)
|
||||
*
|
||||
* If typtype is 'c', typrelid is the OID of the class' entry in pg_class.
|
||||
*/
|
||||
|
@ -56,11 +56,14 @@ WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR
|
||||
-----+---------
|
||||
(0 rows)
|
||||
|
||||
-- Look for basic or enum types that don't have an array type.
|
||||
-- Look for types that should have an array type according to their typtype,
|
||||
-- but don't. We exclude composites here because we have not bothered to
|
||||
-- make array types corresponding to the system catalogs' rowtypes.
|
||||
-- NOTE: as of 9.1, this check finds pg_node_tree, smgr, and unknown.
|
||||
SELECT p1.oid, p1.typname
|
||||
FROM pg_type as p1
|
||||
WHERE p1.typtype in ('b','e') AND p1.typname NOT LIKE E'\\_%' AND NOT EXISTS
|
||||
WHERE p1.typtype not in ('c','d','p') AND p1.typname NOT LIKE E'\\_%'
|
||||
AND NOT EXISTS
|
||||
(SELECT 1 FROM pg_type as p2
|
||||
WHERE p2.typname = ('_' || p1.typname)::name AND
|
||||
p2.typelem = p1.oid and p1.typarray = p2.oid);
|
||||
@ -150,6 +153,19 @@ ORDER BY 1;
|
||||
30 | oidvector | 54 | oidvectorin
|
||||
(2 rows)
|
||||
|
||||
-- Composites, domains, enums, ranges should all use the same input routines
|
||||
SELECT DISTINCT typtype, typinput
|
||||
FROM pg_type AS p1
|
||||
WHERE p1.typtype not in ('b', 'p')
|
||||
ORDER BY 1;
|
||||
typtype | typinput
|
||||
---------+-----------
|
||||
c | record_in
|
||||
d | domain_in
|
||||
e | enum_in
|
||||
r | range_in
|
||||
(4 rows)
|
||||
|
||||
-- Check for bogus typoutput routines
|
||||
-- As of 8.0, this check finds refcursor, which is borrowing
|
||||
-- other types' I/O routines
|
||||
@ -174,6 +190,26 @@ WHERE p1.typoutput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
||||
-----+---------+-----+---------
|
||||
(0 rows)
|
||||
|
||||
-- Composites, enums, ranges should all use the same output routines
|
||||
SELECT DISTINCT typtype, typoutput
|
||||
FROM pg_type AS p1
|
||||
WHERE p1.typtype not in ('b', 'd', 'p')
|
||||
ORDER BY 1;
|
||||
typtype | typoutput
|
||||
---------+------------
|
||||
c | record_out
|
||||
e | enum_out
|
||||
r | range_out
|
||||
(3 rows)
|
||||
|
||||
-- Domains should have same typoutput as their base types
|
||||
SELECT p1.oid, p1.typname, p2.oid, p2.typname
|
||||
FROM pg_type AS p1 LEFT JOIN pg_type AS p2 ON p1.typbasetype = p2.oid
|
||||
WHERE p1.typtype = 'd' AND p1.typoutput IS DISTINCT FROM p2.typoutput;
|
||||
oid | typname | oid | typname
|
||||
-----+---------+-----+---------
|
||||
(0 rows)
|
||||
|
||||
-- Check for bogus typreceive routines
|
||||
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
||||
FROM pg_type AS p1, pg_proc AS p2
|
||||
@ -222,6 +258,19 @@ WHERE p1.typinput = p2.oid AND p1.typreceive = p3.oid AND
|
||||
-----+---------+-----+---------+-----+---------
|
||||
(0 rows)
|
||||
|
||||
-- Composites, domains, enums, ranges should all use the same receive routines
|
||||
SELECT DISTINCT typtype, typreceive
|
||||
FROM pg_type AS p1
|
||||
WHERE p1.typtype not in ('b', 'p')
|
||||
ORDER BY 1;
|
||||
typtype | typreceive
|
||||
---------+-------------
|
||||
c | record_recv
|
||||
d | domain_recv
|
||||
e | enum_recv
|
||||
r | range_recv
|
||||
(4 rows)
|
||||
|
||||
-- Check for bogus typsend routines
|
||||
-- As of 7.4, this check finds refcursor, which is borrowing
|
||||
-- other types' I/O routines
|
||||
@ -246,10 +295,30 @@ WHERE p1.typsend = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
||||
-----+---------+-----+---------
|
||||
(0 rows)
|
||||
|
||||
-- Composites, enums, ranges should all use the same send routines
|
||||
SELECT DISTINCT typtype, typsend
|
||||
FROM pg_type AS p1
|
||||
WHERE p1.typtype not in ('b', 'd', 'p')
|
||||
ORDER BY 1;
|
||||
typtype | typsend
|
||||
---------+-------------
|
||||
c | record_send
|
||||
e | enum_send
|
||||
r | range_send
|
||||
(3 rows)
|
||||
|
||||
-- Domains should have same typsend as their base types
|
||||
SELECT p1.oid, p1.typname, p2.oid, p2.typname
|
||||
FROM pg_type AS p1 LEFT JOIN pg_type AS p2 ON p1.typbasetype = p2.oid
|
||||
WHERE p1.typtype = 'd' AND p1.typsend IS DISTINCT FROM p2.typsend;
|
||||
oid | typname | oid | typname
|
||||
-----+---------+-----+---------
|
||||
(0 rows)
|
||||
|
||||
-- Check for bogus typmodin routines
|
||||
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
||||
FROM pg_type AS p1, pg_proc AS p2
|
||||
WHERE p1.typmodin = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
||||
WHERE p1.typmodin = p2.oid AND NOT
|
||||
(p2.pronargs = 1 AND
|
||||
p2.proargtypes[0] = 'cstring[]'::regtype AND
|
||||
p2.prorettype = 'int4'::regtype AND NOT p2.proretset);
|
||||
@ -260,7 +329,7 @@ WHERE p1.typmodin = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
||||
-- Check for bogus typmodout routines
|
||||
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
||||
FROM pg_type AS p1, pg_proc AS p2
|
||||
WHERE p1.typmodout = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
||||
WHERE p1.typmodout = p2.oid AND NOT
|
||||
(p2.pronargs = 1 AND
|
||||
p2.proargtypes[0] = 'int4'::regtype AND
|
||||
p2.prorettype = 'cstring'::regtype AND NOT p2.proretset);
|
||||
@ -298,7 +367,7 @@ WHERE p1.typarray = p2.oid AND
|
||||
-- Check for bogus typanalyze routines
|
||||
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
||||
FROM pg_type AS p1, pg_proc AS p2
|
||||
WHERE p1.typanalyze = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
||||
WHERE p1.typanalyze = p2.oid AND NOT
|
||||
(p2.pronargs = 1 AND
|
||||
p2.proargtypes[0] = 'internal'::regtype AND
|
||||
p2.prorettype = 'bool'::regtype AND NOT p2.proretset);
|
||||
|
@ -50,12 +50,15 @@ FROM pg_type as p1
|
||||
WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR
|
||||
(p1.typtype != 'c' AND p1.typrelid != 0);
|
||||
|
||||
-- Look for basic or enum types that don't have an array type.
|
||||
-- Look for types that should have an array type according to their typtype,
|
||||
-- but don't. We exclude composites here because we have not bothered to
|
||||
-- make array types corresponding to the system catalogs' rowtypes.
|
||||
-- NOTE: as of 9.1, this check finds pg_node_tree, smgr, and unknown.
|
||||
|
||||
SELECT p1.oid, p1.typname
|
||||
FROM pg_type as p1
|
||||
WHERE p1.typtype in ('b','e') AND p1.typname NOT LIKE E'\\_%' AND NOT EXISTS
|
||||
WHERE p1.typtype not in ('c','d','p') AND p1.typname NOT LIKE E'\\_%'
|
||||
AND NOT EXISTS
|
||||
(SELECT 1 FROM pg_type as p2
|
||||
WHERE p2.typname = ('_' || p1.typname)::name AND
|
||||
p2.typelem = p1.oid and p1.typarray = p2.oid);
|
||||
@ -117,6 +120,12 @@ WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND
|
||||
(p2.oid = 'array_in'::regproc)
|
||||
ORDER BY 1;
|
||||
|
||||
-- Composites, domains, enums, ranges should all use the same input routines
|
||||
SELECT DISTINCT typtype, typinput
|
||||
FROM pg_type AS p1
|
||||
WHERE p1.typtype not in ('b', 'p')
|
||||
ORDER BY 1;
|
||||
|
||||
-- Check for bogus typoutput routines
|
||||
|
||||
-- As of 8.0, this check finds refcursor, which is borrowing
|
||||
@ -135,6 +144,17 @@ FROM pg_type AS p1, pg_proc AS p2
|
||||
WHERE p1.typoutput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
||||
(p2.prorettype = 'cstring'::regtype AND NOT p2.proretset);
|
||||
|
||||
-- Composites, enums, ranges should all use the same output routines
|
||||
SELECT DISTINCT typtype, typoutput
|
||||
FROM pg_type AS p1
|
||||
WHERE p1.typtype not in ('b', 'd', 'p')
|
||||
ORDER BY 1;
|
||||
|
||||
-- Domains should have same typoutput as their base types
|
||||
SELECT p1.oid, p1.typname, p2.oid, p2.typname
|
||||
FROM pg_type AS p1 LEFT JOIN pg_type AS p2 ON p1.typbasetype = p2.oid
|
||||
WHERE p1.typtype = 'd' AND p1.typoutput IS DISTINCT FROM p2.typoutput;
|
||||
|
||||
-- Check for bogus typreceive routines
|
||||
|
||||
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
||||
@ -169,6 +189,12 @@ FROM pg_type AS p1, pg_proc AS p2, pg_proc AS p3
|
||||
WHERE p1.typinput = p2.oid AND p1.typreceive = p3.oid AND
|
||||
p2.pronargs != p3.pronargs;
|
||||
|
||||
-- Composites, domains, enums, ranges should all use the same receive routines
|
||||
SELECT DISTINCT typtype, typreceive
|
||||
FROM pg_type AS p1
|
||||
WHERE p1.typtype not in ('b', 'p')
|
||||
ORDER BY 1;
|
||||
|
||||
-- Check for bogus typsend routines
|
||||
|
||||
-- As of 7.4, this check finds refcursor, which is borrowing
|
||||
@ -187,11 +213,22 @@ FROM pg_type AS p1, pg_proc AS p2
|
||||
WHERE p1.typsend = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
||||
(p2.prorettype = 'bytea'::regtype AND NOT p2.proretset);
|
||||
|
||||
-- Composites, enums, ranges should all use the same send routines
|
||||
SELECT DISTINCT typtype, typsend
|
||||
FROM pg_type AS p1
|
||||
WHERE p1.typtype not in ('b', 'd', 'p')
|
||||
ORDER BY 1;
|
||||
|
||||
-- Domains should have same typsend as their base types
|
||||
SELECT p1.oid, p1.typname, p2.oid, p2.typname
|
||||
FROM pg_type AS p1 LEFT JOIN pg_type AS p2 ON p1.typbasetype = p2.oid
|
||||
WHERE p1.typtype = 'd' AND p1.typsend IS DISTINCT FROM p2.typsend;
|
||||
|
||||
-- Check for bogus typmodin routines
|
||||
|
||||
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
||||
FROM pg_type AS p1, pg_proc AS p2
|
||||
WHERE p1.typmodin = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
||||
WHERE p1.typmodin = p2.oid AND NOT
|
||||
(p2.pronargs = 1 AND
|
||||
p2.proargtypes[0] = 'cstring[]'::regtype AND
|
||||
p2.prorettype = 'int4'::regtype AND NOT p2.proretset);
|
||||
@ -200,7 +237,7 @@ WHERE p1.typmodin = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
||||
|
||||
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
||||
FROM pg_type AS p1, pg_proc AS p2
|
||||
WHERE p1.typmodout = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
||||
WHERE p1.typmodout = p2.oid AND NOT
|
||||
(p2.pronargs = 1 AND
|
||||
p2.proargtypes[0] = 'int4'::regtype AND
|
||||
p2.prorettype = 'cstring'::regtype AND NOT p2.proretset);
|
||||
@ -230,7 +267,7 @@ WHERE p1.typarray = p2.oid AND
|
||||
|
||||
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
||||
FROM pg_type AS p1, pg_proc AS p2
|
||||
WHERE p1.typanalyze = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
||||
WHERE p1.typanalyze = p2.oid AND NOT
|
||||
(p2.pronargs = 1 AND
|
||||
p2.proargtypes[0] = 'internal'::regtype AND
|
||||
p2.prorettype = 'bool'::regtype AND NOT p2.proretset);
|
||||
|
Reference in New Issue
Block a user