postgresql/src/test/regress/expected/type_sanity.out

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

745 lines
25 KiB
Plaintext
Raw Normal View History

--
-- TYPE_SANITY
-- Sanity checks for common errors in making type-related system tables:
-- pg_type, pg_class, pg_attribute, pg_range.
--
-- None of the SELECTs here should ever find any matching entries,
-- so the expected output is easy to maintain ;-).
-- A test failure indicates someone messed up an entry in the system tables.
--
-- NB: we assume the oidjoins test will have caught any dangling links,
-- that is OID or REGPROC fields that are not zero and do not match some
-- row in the linked-to table. However, if we want to enforce that a link
-- field can't be 0, we have to check it here.
-- **************** pg_type ****************
-- Look for illegal values in pg_type fields.
SELECT t1.oid, t1.typname
FROM pg_type as t1
WHERE t1.typnamespace = 0 OR
(t1.typlen <= 0 AND t1.typlen != -1 AND t1.typlen != -2) OR
(t1.typtype not in ('b', 'c', 'd', 'e', 'm', 'p', 'r')) OR
NOT t1.typisdefined OR
(t1.typalign not in ('c', 's', 'i', 'd')) OR
(t1.typstorage not in ('p', 'x', 'e', 'm'));
oid | typname
-----+---------
(0 rows)
-- Look for "pass by value" types that can't be passed by value.
SELECT t1.oid, t1.typname
FROM pg_type as t1
WHERE t1.typbyval AND
(t1.typlen != 1 OR t1.typalign != 'c') AND
(t1.typlen != 2 OR t1.typalign != 's') AND
(t1.typlen != 4 OR t1.typalign != 'i') AND
(t1.typlen != 8 OR t1.typalign != 'd');
oid | typname
-----+---------
(0 rows)
-- Look for "toastable" types that aren't varlena.
SELECT t1.oid, t1.typname
FROM pg_type as t1
WHERE t1.typstorage != 'p' AND
(t1.typbyval OR t1.typlen != -1);
oid | typname
-----+---------
(0 rows)
-- Look for complex types that do not have a typrelid entry,
-- or basic types that do.
SELECT t1.oid, t1.typname
FROM pg_type as t1
WHERE (t1.typtype = 'c' AND t1.typrelid = 0) OR
(t1.typtype != 'c' AND t1.typrelid != 0);
oid | typname
-----+---------
(0 rows)
-- Look for types that should have an array type but don't.
-- Generally anything that's not a pseudotype should have an array type.
-- However, we do have a small number of exceptions.
SELECT t1.oid, t1.typname
FROM pg_type as t1
WHERE t1.typtype not in ('p') AND t1.typname NOT LIKE E'\\_%'
AND NOT EXISTS
(SELECT 1 FROM pg_type as t2
WHERE t2.typname = ('_' || t1.typname)::name AND
t2.typelem = t1.oid and t1.typarray = t2.oid)
ORDER BY t1.oid;
oid | typname
------+------------------------------
Implement multivariate n-distinct coefficients Add support for explicitly declared statistic objects (CREATE STATISTICS), allowing collection of statistics on more complex combinations that individual table columns. Companion commands DROP STATISTICS and ALTER STATISTICS ... OWNER TO / SET SCHEMA / RENAME are added too. All this DDL has been designed so that more statistic types can be added later on, such as multivariate most-common-values and multivariate histograms between columns of a single table, leaving room for permitting columns on multiple tables, too, as well as expressions. This commit only adds support for collection of n-distinct coefficient on user-specified sets of columns in a single table. This is useful to estimate number of distinct groups in GROUP BY and DISTINCT clauses; estimation errors there can cause over-allocation of memory in hashed aggregates, for instance, so it's a worthwhile problem to solve. A new special pseudo-type pg_ndistinct is used. (num-distinct estimation was deemed sufficiently useful by itself that this is worthwhile even if no further statistic types are added immediately; so much so that another version of essentially the same functionality was submitted by Kyotaro Horiguchi: https://postgr.es/m/20150828.173334.114731693.horiguchi.kyotaro@lab.ntt.co.jp though this commit does not use that code.) Author: Tomas Vondra. Some code rework by Álvaro. Reviewed-by: Dean Rasheed, David Rowley, Kyotaro Horiguchi, Jeff Janes, Ideriha Takeshi Discussion: https://postgr.es/m/543AFA15.4080608@fuzzy.cz https://postgr.es/m/20170320190220.ixlaueanxegqd5gr@alvherre.pgsql
2017-03-24 18:06:10 +01:00
194 | pg_node_tree
3361 | pg_ndistinct
3402 | pg_dependencies
BRIN bloom indexes Adds a BRIN opclass using a Bloom filter to summarize the range. Indexes using the new opclasses allow only equality queries (similar to hash indexes), but that works fine for data like UUID, MAC addresses etc. for which range queries are not very common. This also means the indexes work for data that is not well correlated to physical location within the table, or perhaps even entirely random (which is a common issue with existing BRIN minmax opclasses). It's possible to specify opclass parameters with the usual Bloom filter parameters, i.e. the desired false-positive rate and the expected number of distinct values per page range. CREATE TABLE t (a int); CREATE INDEX ON t USING brin (a int4_bloom_ops(false_positive_rate = 0.05, n_distinct_per_range = 100)); The opclasses do not operate on the indexed values directly, but compute a 32-bit hash first, and the Bloom filter is built on the hash value. Collisions should not be a huge issue though, as the number of distinct values in a page ranges is usually fairly small. Bump catversion, due to various catalog changes. Author: Tomas Vondra <tomas.vondra@postgresql.org> Reviewed-by: Alvaro Herrera <alvherre@alvh.no-ip.org> Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com> Reviewed-by: Sokolov Yura <y.sokolov@postgrespro.ru> Reviewed-by: Nico Williams <nico@cryptonector.com> Reviewed-by: John Naylor <john.naylor@enterprisedb.com> Discussion: https://postgr.es/m/c1138ead-7668-f0e1-0638-c3be3237e812@2ndquadrant.com Discussion: https://postgr.es/m/5d78b774-7e9c-c94e-12cf-fef51cc89b1a%402ndquadrant.com
2021-03-26 13:35:29 +01:00
4600 | pg_brin_bloom_summary
4601 | pg_brin_minmax_multi_summary
5017 | pg_mcv_list
(6 rows)
Support subscripting of arbitrary types, not only arrays. This patch generalizes the subscripting infrastructure so that any data type can be subscripted, if it provides a handler function to define what that means. Traditional variable-length (varlena) arrays all use array_subscript_handler(), while the existing fixed-length types that support subscripting use raw_array_subscript_handler(). It's expected that other types that want to use subscripting notation will define their own handlers. (This patch provides no such new features, though; it only lays the foundation for them.) To do this, move the parser's semantic processing of subscripts (including coercion to whatever data type is required) into a method callback supplied by the handler. On the execution side, replace the ExecEvalSubscriptingRef* layer of functions with direct calls to callback-supplied execution routines. (Thus, essentially no new run-time overhead should be caused by this patch. Indeed, there is room to remove some overhead by supplying specialized execution routines. This patch does a little bit in that line, but more could be done.) Additional work is required here and there to remove formerly hard-wired assumptions about the result type, collation, etc of a SubscriptingRef expression node; and to remove assumptions that the subscript values must be integers. One useful side-effect of this is that we now have a less squishy mechanism for identifying whether a data type is a "true" array: instead of wiring in weird rules about typlen, we can look to see if pg_type.typsubscript == F_ARRAY_SUBSCRIPT_HANDLER. For this to be bulletproof, we have to forbid user-defined types from using that handler directly; but there seems no good reason for them to do so. This patch also removes assumptions that the number of subscripts is limited to MAXDIM (6), or indeed has any hard-wired limit. That limit still applies to types handled by array_subscript_handler or raw_array_subscript_handler, but to discourage other dependencies on this constant, I've moved it from c.h to utils/array.h. Dmitry Dolgov, reviewed at various times by Tom Lane, Arthur Zakirov, Peter Eisentraut, Pavel Stehule Discussion: https://postgr.es/m/CA+q6zcVDuGBv=M0FqBYX8DPebS3F_0KQ6OVFobGJPM507_SZ_w@mail.gmail.com Discussion: https://postgr.es/m/CA+q6zcVovR+XY4mfk-7oNk-rF91gH0PebnNfuUjuuDsyHjOcVA@mail.gmail.com
2020-12-09 18:40:37 +01:00
-- Make sure typarray points to a "true" array type of our own base
SELECT t1.oid, t1.typname as basetype, t2.typname as arraytype,
t2.typsubscript
FROM pg_type t1 LEFT JOIN pg_type t2 ON (t1.typarray = t2.oid)
WHERE t1.typarray <> 0 AND
(t2.oid IS NULL OR
t2.typsubscript <> 'array_subscript_handler'::regproc);
Support subscripting of arbitrary types, not only arrays. This patch generalizes the subscripting infrastructure so that any data type can be subscripted, if it provides a handler function to define what that means. Traditional variable-length (varlena) arrays all use array_subscript_handler(), while the existing fixed-length types that support subscripting use raw_array_subscript_handler(). It's expected that other types that want to use subscripting notation will define their own handlers. (This patch provides no such new features, though; it only lays the foundation for them.) To do this, move the parser's semantic processing of subscripts (including coercion to whatever data type is required) into a method callback supplied by the handler. On the execution side, replace the ExecEvalSubscriptingRef* layer of functions with direct calls to callback-supplied execution routines. (Thus, essentially no new run-time overhead should be caused by this patch. Indeed, there is room to remove some overhead by supplying specialized execution routines. This patch does a little bit in that line, but more could be done.) Additional work is required here and there to remove formerly hard-wired assumptions about the result type, collation, etc of a SubscriptingRef expression node; and to remove assumptions that the subscript values must be integers. One useful side-effect of this is that we now have a less squishy mechanism for identifying whether a data type is a "true" array: instead of wiring in weird rules about typlen, we can look to see if pg_type.typsubscript == F_ARRAY_SUBSCRIPT_HANDLER. For this to be bulletproof, we have to forbid user-defined types from using that handler directly; but there seems no good reason for them to do so. This patch also removes assumptions that the number of subscripts is limited to MAXDIM (6), or indeed has any hard-wired limit. That limit still applies to types handled by array_subscript_handler or raw_array_subscript_handler, but to discourage other dependencies on this constant, I've moved it from c.h to utils/array.h. Dmitry Dolgov, reviewed at various times by Tom Lane, Arthur Zakirov, Peter Eisentraut, Pavel Stehule Discussion: https://postgr.es/m/CA+q6zcVDuGBv=M0FqBYX8DPebS3F_0KQ6OVFobGJPM507_SZ_w@mail.gmail.com Discussion: https://postgr.es/m/CA+q6zcVovR+XY4mfk-7oNk-rF91gH0PebnNfuUjuuDsyHjOcVA@mail.gmail.com
2020-12-09 18:40:37 +01:00
oid | basetype | arraytype | typsubscript
-----+----------+-----------+--------------
(0 rows)
-- Look for range types that do not have a pg_range entry
SELECT t1.oid, t1.typname
FROM pg_type as t1
WHERE t1.typtype = 'r' AND
NOT EXISTS(SELECT 1 FROM pg_range r WHERE rngtypid = t1.oid);
oid | typname
-----+---------
(0 rows)
-- Look for range types whose typalign isn't sufficient
SELECT t1.oid, t1.typname, t1.typalign, t2.typname, t2.typalign
FROM pg_type as t1
LEFT JOIN pg_range as r ON rngtypid = t1.oid
LEFT JOIN pg_type as t2 ON rngsubtype = t2.oid
WHERE t1.typtype = 'r' AND
(t1.typalign != (CASE WHEN t2.typalign = 'd' THEN 'd'::"char"
ELSE 'i'::"char" END)
OR t2.oid IS NULL);
oid | typname | typalign | typname | typalign
-----+---------+----------+---------+----------
(0 rows)
-- Text conversion routines must be provided.
SELECT t1.oid, t1.typname
FROM pg_type as t1
WHERE (t1.typinput = 0 OR t1.typoutput = 0);
oid | typname
-----+---------
(0 rows)
-- Check for bogus typinput routines
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typinput = p1.oid AND NOT
((p1.pronargs = 1 AND p1.proargtypes[0] = 'cstring'::regtype) OR
(p1.pronargs = 2 AND p1.proargtypes[0] = 'cstring'::regtype AND
p1.proargtypes[1] = 'oid'::regtype) OR
(p1.pronargs = 3 AND p1.proargtypes[0] = 'cstring'::regtype AND
p1.proargtypes[1] = 'oid'::regtype AND
p1.proargtypes[2] = 'int4'::regtype));
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
-- As of 8.0, this check finds refcursor, which is borrowing
-- other types' I/O routines
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typinput = p1.oid AND t1.typtype in ('b', 'p') AND NOT
(t1.typelem != 0 AND t1.typlen < 0) AND NOT
(p1.prorettype = t1.oid AND NOT p1.proretset)
ORDER BY 1;
oid | typname | oid | proname
------+-----------+-----+---------
1790 | refcursor | 46 | textin
(1 row)
-- Varlena array types will point to array_in
-- Exception as of 8.1: int2vector and oidvector have their own I/O routines
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typinput = p1.oid AND
(t1.typelem != 0 AND t1.typlen < 0) AND NOT
(p1.oid = 'array_in'::regproc)
ORDER BY 1;
oid | typname | oid | proname
-----+------------+-----+--------------
22 | int2vector | 40 | int2vectorin
30 | oidvector | 54 | oidvectorin
(2 rows)
-- typinput routines should not be volatile
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typinput = p1.oid AND p1.provolatile NOT IN ('i', 's');
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
2020-12-20 05:20:33 +01:00
-- Composites, domains, enums, multiranges, ranges should all use the same input routines
SELECT DISTINCT typtype, typinput
FROM pg_type AS t1
WHERE t1.typtype not in ('b', 'p')
ORDER BY 1;
2020-12-20 05:20:33 +01:00
typtype | typinput
---------+---------------
c | record_in
d | domain_in
e | enum_in
2020-12-20 05:20:33 +01:00
m | multirange_in
r | range_in
2020-12-20 05:20:33 +01:00
(5 rows)
-- Check for bogus typoutput routines
-- As of 8.0, this check finds refcursor, which is borrowing
-- other types' I/O routines
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typoutput = p1.oid AND t1.typtype in ('b', 'p') AND NOT
(p1.pronargs = 1 AND
(p1.proargtypes[0] = t1.oid OR
(p1.oid = 'array_out'::regproc AND
t1.typelem != 0 AND t1.typlen = -1)))
ORDER BY 1;
oid | typname | oid | proname
------+-----------+-----+---------
1790 | refcursor | 47 | textout
(1 row)
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typoutput = p1.oid AND NOT
(p1.prorettype = 'cstring'::regtype AND NOT p1.proretset);
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
-- typoutput routines should not be volatile
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typoutput = p1.oid AND p1.provolatile NOT IN ('i', 's');
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
2020-12-20 05:20:33 +01:00
-- Composites, enums, multiranges, ranges should all use the same output routines
SELECT DISTINCT typtype, typoutput
FROM pg_type AS t1
WHERE t1.typtype not in ('b', 'd', 'p')
ORDER BY 1;
2020-12-20 05:20:33 +01:00
typtype | typoutput
---------+----------------
c | record_out
e | enum_out
2020-12-20 05:20:33 +01:00
m | multirange_out
r | range_out
2020-12-20 05:20:33 +01:00
(4 rows)
-- Domains should have same typoutput as their base types
SELECT t1.oid, t1.typname, t2.oid, t2.typname
FROM pg_type AS t1 LEFT JOIN pg_type AS t2 ON t1.typbasetype = t2.oid
WHERE t1.typtype = 'd' AND t1.typoutput IS DISTINCT FROM t2.typoutput;
oid | typname | oid | typname
-----+---------+-----+---------
(0 rows)
-- Check for bogus typreceive routines
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typreceive = p1.oid AND NOT
((p1.pronargs = 1 AND p1.proargtypes[0] = 'internal'::regtype) OR
(p1.pronargs = 2 AND p1.proargtypes[0] = 'internal'::regtype AND
p1.proargtypes[1] = 'oid'::regtype) OR
(p1.pronargs = 3 AND p1.proargtypes[0] = 'internal'::regtype AND
p1.proargtypes[1] = 'oid'::regtype AND
p1.proargtypes[2] = 'int4'::regtype));
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
-- As of 7.4, this check finds refcursor, which is borrowing
-- other types' I/O routines
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typreceive = p1.oid AND t1.typtype in ('b', 'p') AND NOT
(t1.typelem != 0 AND t1.typlen < 0) AND NOT
(p1.prorettype = t1.oid AND NOT p1.proretset)
ORDER BY 1;
oid | typname | oid | proname
------+-----------+------+----------
1790 | refcursor | 2414 | textrecv
(1 row)
-- Varlena array types will point to array_recv
-- Exception as of 8.1: int2vector and oidvector have their own I/O routines
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typreceive = p1.oid AND
(t1.typelem != 0 AND t1.typlen < 0) AND NOT
(p1.oid = 'array_recv'::regproc)
ORDER BY 1;
oid | typname | oid | proname
-----+------------+------+----------------
22 | int2vector | 2410 | int2vectorrecv
30 | oidvector | 2420 | oidvectorrecv
(2 rows)
-- Suspicious if typreceive doesn't take same number of args as typinput
SELECT t1.oid, t1.typname, p1.oid, p1.proname, p2.oid, p2.proname
FROM pg_type AS t1, pg_proc AS p1, pg_proc AS p2
WHERE t1.typinput = p1.oid AND t1.typreceive = p2.oid AND
p1.pronargs != p2.pronargs;
oid | typname | oid | proname | oid | proname
-----+---------+-----+---------+-----+---------
(0 rows)
-- typreceive routines should not be volatile
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typreceive = p1.oid AND p1.provolatile NOT IN ('i', 's');
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
2020-12-20 05:20:33 +01:00
-- Composites, domains, enums, multiranges, ranges should all use the same receive routines
SELECT DISTINCT typtype, typreceive
FROM pg_type AS t1
WHERE t1.typtype not in ('b', 'p')
ORDER BY 1;
2020-12-20 05:20:33 +01:00
typtype | typreceive
---------+-----------------
c | record_recv
d | domain_recv
e | enum_recv
2020-12-20 05:20:33 +01:00
m | multirange_recv
r | range_recv
2020-12-20 05:20:33 +01:00
(5 rows)
-- Check for bogus typsend routines
-- As of 7.4, this check finds refcursor, which is borrowing
-- other types' I/O routines
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typsend = p1.oid AND t1.typtype in ('b', 'p') AND NOT
(p1.pronargs = 1 AND
(p1.proargtypes[0] = t1.oid OR
(p1.oid = 'array_send'::regproc AND
t1.typelem != 0 AND t1.typlen = -1)))
ORDER BY 1;
oid | typname | oid | proname
------+-----------+------+----------
1790 | refcursor | 2415 | textsend
(1 row)
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typsend = p1.oid AND NOT
(p1.prorettype = 'bytea'::regtype AND NOT p1.proretset);
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
-- typsend routines should not be volatile
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typsend = p1.oid AND p1.provolatile NOT IN ('i', 's');
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
2020-12-20 05:20:33 +01:00
-- Composites, enums, multiranges, ranges should all use the same send routines
SELECT DISTINCT typtype, typsend
FROM pg_type AS t1
WHERE t1.typtype not in ('b', 'd', 'p')
ORDER BY 1;
2020-12-20 05:20:33 +01:00
typtype | typsend
---------+-----------------
c | record_send
e | enum_send
2020-12-20 05:20:33 +01:00
m | multirange_send
r | range_send
2020-12-20 05:20:33 +01:00
(4 rows)
-- Domains should have same typsend as their base types
SELECT t1.oid, t1.typname, t2.oid, t2.typname
FROM pg_type AS t1 LEFT JOIN pg_type AS t2 ON t1.typbasetype = t2.oid
WHERE t1.typtype = 'd' AND t1.typsend IS DISTINCT FROM t2.typsend;
oid | typname | oid | typname
-----+---------+-----+---------
(0 rows)
-- Check for bogus typmodin routines
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typmodin = p1.oid AND NOT
(p1.pronargs = 1 AND
p1.proargtypes[0] = 'cstring[]'::regtype AND
p1.prorettype = 'int4'::regtype AND NOT p1.proretset);
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
-- typmodin routines should not be volatile
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typmodin = p1.oid AND p1.provolatile NOT IN ('i', 's');
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
-- Check for bogus typmodout routines
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typmodout = p1.oid AND NOT
(p1.pronargs = 1 AND
p1.proargtypes[0] = 'int4'::regtype AND
p1.prorettype = 'cstring'::regtype AND NOT p1.proretset);
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
-- typmodout routines should not be volatile
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typmodout = p1.oid AND p1.provolatile NOT IN ('i', 's');
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
-- Array types should have same typmodin/out as their element types
SELECT t1.oid, t1.typname, t2.oid, t2.typname
FROM pg_type AS t1, pg_type AS t2
WHERE t1.typelem = t2.oid AND NOT
(t1.typmodin = t2.typmodin AND t1.typmodout = t2.typmodout);
oid | typname | oid | typname
-----+---------+-----+---------
(0 rows)
-- Array types should have same typdelim as their element types
SELECT t1.oid, t1.typname, t2.oid, t2.typname
FROM pg_type AS t1, pg_type AS t2
WHERE t1.typarray = t2.oid AND NOT (t1.typdelim = t2.typdelim);
oid | typname | oid | typname
-----+---------+-----+---------
(0 rows)
-- Look for array types whose typalign isn't sufficient
SELECT t1.oid, t1.typname, t1.typalign, t2.typname, t2.typalign
FROM pg_type AS t1, pg_type AS t2
WHERE t1.typarray = t2.oid AND
t2.typalign != (CASE WHEN t1.typalign = 'd' THEN 'd'::"char"
ELSE 'i'::"char" END);
oid | typname | typalign | typname | typalign
-----+---------+----------+---------+----------
(0 rows)
Support subscripting of arbitrary types, not only arrays. This patch generalizes the subscripting infrastructure so that any data type can be subscripted, if it provides a handler function to define what that means. Traditional variable-length (varlena) arrays all use array_subscript_handler(), while the existing fixed-length types that support subscripting use raw_array_subscript_handler(). It's expected that other types that want to use subscripting notation will define their own handlers. (This patch provides no such new features, though; it only lays the foundation for them.) To do this, move the parser's semantic processing of subscripts (including coercion to whatever data type is required) into a method callback supplied by the handler. On the execution side, replace the ExecEvalSubscriptingRef* layer of functions with direct calls to callback-supplied execution routines. (Thus, essentially no new run-time overhead should be caused by this patch. Indeed, there is room to remove some overhead by supplying specialized execution routines. This patch does a little bit in that line, but more could be done.) Additional work is required here and there to remove formerly hard-wired assumptions about the result type, collation, etc of a SubscriptingRef expression node; and to remove assumptions that the subscript values must be integers. One useful side-effect of this is that we now have a less squishy mechanism for identifying whether a data type is a "true" array: instead of wiring in weird rules about typlen, we can look to see if pg_type.typsubscript == F_ARRAY_SUBSCRIPT_HANDLER. For this to be bulletproof, we have to forbid user-defined types from using that handler directly; but there seems no good reason for them to do so. This patch also removes assumptions that the number of subscripts is limited to MAXDIM (6), or indeed has any hard-wired limit. That limit still applies to types handled by array_subscript_handler or raw_array_subscript_handler, but to discourage other dependencies on this constant, I've moved it from c.h to utils/array.h. Dmitry Dolgov, reviewed at various times by Tom Lane, Arthur Zakirov, Peter Eisentraut, Pavel Stehule Discussion: https://postgr.es/m/CA+q6zcVDuGBv=M0FqBYX8DPebS3F_0KQ6OVFobGJPM507_SZ_w@mail.gmail.com Discussion: https://postgr.es/m/CA+q6zcVovR+XY4mfk-7oNk-rF91gH0PebnNfuUjuuDsyHjOcVA@mail.gmail.com
2020-12-09 18:40:37 +01:00
-- Check for typelem set without a handler
SELECT t1.oid, t1.typname, t1.typelem
FROM pg_type AS t1
WHERE t1.typelem != 0 AND t1.typsubscript = 0;
Support subscripting of arbitrary types, not only arrays. This patch generalizes the subscripting infrastructure so that any data type can be subscripted, if it provides a handler function to define what that means. Traditional variable-length (varlena) arrays all use array_subscript_handler(), while the existing fixed-length types that support subscripting use raw_array_subscript_handler(). It's expected that other types that want to use subscripting notation will define their own handlers. (This patch provides no such new features, though; it only lays the foundation for them.) To do this, move the parser's semantic processing of subscripts (including coercion to whatever data type is required) into a method callback supplied by the handler. On the execution side, replace the ExecEvalSubscriptingRef* layer of functions with direct calls to callback-supplied execution routines. (Thus, essentially no new run-time overhead should be caused by this patch. Indeed, there is room to remove some overhead by supplying specialized execution routines. This patch does a little bit in that line, but more could be done.) Additional work is required here and there to remove formerly hard-wired assumptions about the result type, collation, etc of a SubscriptingRef expression node; and to remove assumptions that the subscript values must be integers. One useful side-effect of this is that we now have a less squishy mechanism for identifying whether a data type is a "true" array: instead of wiring in weird rules about typlen, we can look to see if pg_type.typsubscript == F_ARRAY_SUBSCRIPT_HANDLER. For this to be bulletproof, we have to forbid user-defined types from using that handler directly; but there seems no good reason for them to do so. This patch also removes assumptions that the number of subscripts is limited to MAXDIM (6), or indeed has any hard-wired limit. That limit still applies to types handled by array_subscript_handler or raw_array_subscript_handler, but to discourage other dependencies on this constant, I've moved it from c.h to utils/array.h. Dmitry Dolgov, reviewed at various times by Tom Lane, Arthur Zakirov, Peter Eisentraut, Pavel Stehule Discussion: https://postgr.es/m/CA+q6zcVDuGBv=M0FqBYX8DPebS3F_0KQ6OVFobGJPM507_SZ_w@mail.gmail.com Discussion: https://postgr.es/m/CA+q6zcVovR+XY4mfk-7oNk-rF91gH0PebnNfuUjuuDsyHjOcVA@mail.gmail.com
2020-12-09 18:40:37 +01:00
oid | typname | typelem
-----+---------+---------
(0 rows)
-- Check for misuse of standard subscript handlers
SELECT t1.oid, t1.typname,
t1.typelem, t1.typlen, t1.typbyval
FROM pg_type AS t1
WHERE t1.typsubscript = 'array_subscript_handler'::regproc AND NOT
(t1.typelem != 0 AND t1.typlen = -1 AND NOT t1.typbyval);
Support subscripting of arbitrary types, not only arrays. This patch generalizes the subscripting infrastructure so that any data type can be subscripted, if it provides a handler function to define what that means. Traditional variable-length (varlena) arrays all use array_subscript_handler(), while the existing fixed-length types that support subscripting use raw_array_subscript_handler(). It's expected that other types that want to use subscripting notation will define their own handlers. (This patch provides no such new features, though; it only lays the foundation for them.) To do this, move the parser's semantic processing of subscripts (including coercion to whatever data type is required) into a method callback supplied by the handler. On the execution side, replace the ExecEvalSubscriptingRef* layer of functions with direct calls to callback-supplied execution routines. (Thus, essentially no new run-time overhead should be caused by this patch. Indeed, there is room to remove some overhead by supplying specialized execution routines. This patch does a little bit in that line, but more could be done.) Additional work is required here and there to remove formerly hard-wired assumptions about the result type, collation, etc of a SubscriptingRef expression node; and to remove assumptions that the subscript values must be integers. One useful side-effect of this is that we now have a less squishy mechanism for identifying whether a data type is a "true" array: instead of wiring in weird rules about typlen, we can look to see if pg_type.typsubscript == F_ARRAY_SUBSCRIPT_HANDLER. For this to be bulletproof, we have to forbid user-defined types from using that handler directly; but there seems no good reason for them to do so. This patch also removes assumptions that the number of subscripts is limited to MAXDIM (6), or indeed has any hard-wired limit. That limit still applies to types handled by array_subscript_handler or raw_array_subscript_handler, but to discourage other dependencies on this constant, I've moved it from c.h to utils/array.h. Dmitry Dolgov, reviewed at various times by Tom Lane, Arthur Zakirov, Peter Eisentraut, Pavel Stehule Discussion: https://postgr.es/m/CA+q6zcVDuGBv=M0FqBYX8DPebS3F_0KQ6OVFobGJPM507_SZ_w@mail.gmail.com Discussion: https://postgr.es/m/CA+q6zcVovR+XY4mfk-7oNk-rF91gH0PebnNfuUjuuDsyHjOcVA@mail.gmail.com
2020-12-09 18:40:37 +01:00
oid | typname | typelem | typlen | typbyval
-----+---------+---------+--------+----------
(0 rows)
SELECT t1.oid, t1.typname,
t1.typelem, t1.typlen, t1.typbyval
FROM pg_type AS t1
WHERE t1.typsubscript = 'raw_array_subscript_handler'::regproc AND NOT
(t1.typelem != 0 AND t1.typlen > 0 AND NOT t1.typbyval);
Support subscripting of arbitrary types, not only arrays. This patch generalizes the subscripting infrastructure so that any data type can be subscripted, if it provides a handler function to define what that means. Traditional variable-length (varlena) arrays all use array_subscript_handler(), while the existing fixed-length types that support subscripting use raw_array_subscript_handler(). It's expected that other types that want to use subscripting notation will define their own handlers. (This patch provides no such new features, though; it only lays the foundation for them.) To do this, move the parser's semantic processing of subscripts (including coercion to whatever data type is required) into a method callback supplied by the handler. On the execution side, replace the ExecEvalSubscriptingRef* layer of functions with direct calls to callback-supplied execution routines. (Thus, essentially no new run-time overhead should be caused by this patch. Indeed, there is room to remove some overhead by supplying specialized execution routines. This patch does a little bit in that line, but more could be done.) Additional work is required here and there to remove formerly hard-wired assumptions about the result type, collation, etc of a SubscriptingRef expression node; and to remove assumptions that the subscript values must be integers. One useful side-effect of this is that we now have a less squishy mechanism for identifying whether a data type is a "true" array: instead of wiring in weird rules about typlen, we can look to see if pg_type.typsubscript == F_ARRAY_SUBSCRIPT_HANDLER. For this to be bulletproof, we have to forbid user-defined types from using that handler directly; but there seems no good reason for them to do so. This patch also removes assumptions that the number of subscripts is limited to MAXDIM (6), or indeed has any hard-wired limit. That limit still applies to types handled by array_subscript_handler or raw_array_subscript_handler, but to discourage other dependencies on this constant, I've moved it from c.h to utils/array.h. Dmitry Dolgov, reviewed at various times by Tom Lane, Arthur Zakirov, Peter Eisentraut, Pavel Stehule Discussion: https://postgr.es/m/CA+q6zcVDuGBv=M0FqBYX8DPebS3F_0KQ6OVFobGJPM507_SZ_w@mail.gmail.com Discussion: https://postgr.es/m/CA+q6zcVovR+XY4mfk-7oNk-rF91gH0PebnNfuUjuuDsyHjOcVA@mail.gmail.com
2020-12-09 18:40:37 +01:00
oid | typname | typelem | typlen | typbyval
-----+---------+---------+--------+----------
(0 rows)
-- Check for bogus typanalyze routines
SELECT t1.oid, t1.typname, p1.oid, p1.proname
FROM pg_type AS t1, pg_proc AS p1
WHERE t1.typanalyze = p1.oid AND NOT
(p1.pronargs = 1 AND
p1.proargtypes[0] = 'internal'::regtype AND
p1.prorettype = 'bool'::regtype AND NOT p1.proretset);
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
-- there does not seem to be a reason to care about volatility of typanalyze
-- domains inherit their base type's typanalyze
SELECT d.oid, d.typname, d.typanalyze, t.oid, t.typname, t.typanalyze
FROM pg_type d JOIN pg_type t ON d.typbasetype = t.oid
WHERE d.typanalyze != t.typanalyze;
oid | typname | typanalyze | oid | typname | typanalyze
-----+---------+------------+-----+---------+------------
(0 rows)
-- range_typanalyze should be used for all and only range types
-- (but exclude domains, which we checked above)
SELECT t.oid, t.typname, t.typanalyze
FROM pg_type t LEFT JOIN pg_range r on t.oid = r.rngtypid
WHERE t.typbasetype = 0 AND
(t.typanalyze = 'range_typanalyze'::regproc) != (r.rngtypid IS NOT NULL);
oid | typname | typanalyze
-----+---------+------------
(0 rows)
-- array_typanalyze should be used for all and only array types
-- (but exclude domains, which we checked above)
-- As of 9.2 this finds int2vector and oidvector, which are weird anyway
SELECT t.oid, t.typname, t.typanalyze
FROM pg_type t
WHERE t.typbasetype = 0 AND
(t.typanalyze = 'array_typanalyze'::regproc) !=
Support subscripting of arbitrary types, not only arrays. This patch generalizes the subscripting infrastructure so that any data type can be subscripted, if it provides a handler function to define what that means. Traditional variable-length (varlena) arrays all use array_subscript_handler(), while the existing fixed-length types that support subscripting use raw_array_subscript_handler(). It's expected that other types that want to use subscripting notation will define their own handlers. (This patch provides no such new features, though; it only lays the foundation for them.) To do this, move the parser's semantic processing of subscripts (including coercion to whatever data type is required) into a method callback supplied by the handler. On the execution side, replace the ExecEvalSubscriptingRef* layer of functions with direct calls to callback-supplied execution routines. (Thus, essentially no new run-time overhead should be caused by this patch. Indeed, there is room to remove some overhead by supplying specialized execution routines. This patch does a little bit in that line, but more could be done.) Additional work is required here and there to remove formerly hard-wired assumptions about the result type, collation, etc of a SubscriptingRef expression node; and to remove assumptions that the subscript values must be integers. One useful side-effect of this is that we now have a less squishy mechanism for identifying whether a data type is a "true" array: instead of wiring in weird rules about typlen, we can look to see if pg_type.typsubscript == F_ARRAY_SUBSCRIPT_HANDLER. For this to be bulletproof, we have to forbid user-defined types from using that handler directly; but there seems no good reason for them to do so. This patch also removes assumptions that the number of subscripts is limited to MAXDIM (6), or indeed has any hard-wired limit. That limit still applies to types handled by array_subscript_handler or raw_array_subscript_handler, but to discourage other dependencies on this constant, I've moved it from c.h to utils/array.h. Dmitry Dolgov, reviewed at various times by Tom Lane, Arthur Zakirov, Peter Eisentraut, Pavel Stehule Discussion: https://postgr.es/m/CA+q6zcVDuGBv=M0FqBYX8DPebS3F_0KQ6OVFobGJPM507_SZ_w@mail.gmail.com Discussion: https://postgr.es/m/CA+q6zcVovR+XY4mfk-7oNk-rF91gH0PebnNfuUjuuDsyHjOcVA@mail.gmail.com
2020-12-09 18:40:37 +01:00
(t.typsubscript = 'array_subscript_handler'::regproc)
ORDER BY 1;
oid | typname | typanalyze
-----+------------+------------
22 | int2vector | -
30 | oidvector | -
(2 rows)
-- **************** pg_class ****************
-- Look for illegal values in pg_class fields
SELECT c1.oid, c1.relname
FROM pg_class as c1
WHERE relkind NOT IN ('r', 'i', 'S', 't', 'v', 'm', 'c', 'f', 'p', 'I') OR
relpersistence NOT IN ('p', 'u', 't') OR
relreplident NOT IN ('d', 'n', 'f', 'i');
oid | relname
-----+---------
(0 rows)
-- All tables, indexes, partitioned indexes and matviews should have an
-- access method.
SELECT c1.oid, c1.relname
FROM pg_class as c1
WHERE c1.relkind NOT IN ('S', 'v', 'f', 'c', 'p') and
c1.relam = 0;
tableam: introduce table AM infrastructure. This introduces the concept of table access methods, i.e. CREATE ACCESS METHOD ... TYPE TABLE and CREATE TABLE ... USING (storage-engine). No table access functionality is delegated to table AMs as of this commit, that'll be done in following commits. Subsequent commits will incrementally abstract table access functionality to be routed through table access methods. That change is too large to be reviewed & committed at once, so it'll be done incrementally. Docs will be updated at the end, as adding them incrementally would likely make them less coherent, and definitely is a lot more work, without a lot of benefit. Table access methods are specified similar to index access methods, i.e. pg_am.amhandler returns, as INTERNAL, a pointer to a struct with callbacks. In contrast to index AMs that struct needs to live as long as a backend, typically that's achieved by just returning a pointer to a constant struct. Psql's \d+ now displays a table's access method. That can be disabled with HIDE_TABLEAM=true, which is mainly useful so regression tests can be run against different AMs. It's quite possible that this behaviour still needs to be fine tuned. For now it's not allowed to set a table AM for a partitioned table, as we've not resolved how partitions would inherit that. Disallowing allows us to introduce, if we decide that's the way forward, such a behaviour without a compatibility break. Catversion bumped, to add the heap table AM and references to it. Author: Haribabu Kommi, Andres Freund, Alvaro Herrera, Dimitri Golgov and others Discussion: https://postgr.es/m/20180703070645.wchpu5muyto5n647@alap3.anarazel.de https://postgr.es/m/20160812231527.GA690404@alvherre.pgsql https://postgr.es/m/20190107235616.6lur25ph22u5u5av@alap3.anarazel.de https://postgr.es/m/20190304234700.w5tmhducs5wxgzls@alap3.anarazel.de
2019-03-06 18:54:38 +01:00
oid | relname
-----+---------
(0 rows)
-- Conversely, sequences, views, foreign tables, types and partitioned
-- tables shouldn't have them.
SELECT c1.oid, c1.relname
FROM pg_class as c1
WHERE c1.relkind IN ('S', 'v', 'f', 'c', 'p') and
c1.relam != 0;
oid | relname
-----+---------
(0 rows)
-- Indexes and partitioned indexes should have AMs of type 'i'.
SELECT pc.oid, pc.relname, pa.amname, pa.amtype
FROM pg_class as pc JOIN pg_am AS pa ON (pc.relam = pa.oid)
WHERE pc.relkind IN ('i', 'I') and
pa.amtype != 'i';
oid | relname | amname | amtype
-----+---------+--------+--------
(0 rows)
-- Tables, matviews etc should have AMs of type 't'
SELECT pc.oid, pc.relname, pa.amname, pa.amtype
FROM pg_class as pc JOIN pg_am AS pa ON (pc.relam = pa.oid)
WHERE pc.relkind IN ('r', 't', 'm') and
pa.amtype != 't';
oid | relname | amname | amtype
-----+---------+--------+--------
(0 rows)
-- **************** pg_attribute ****************
-- Look for illegal values in pg_attribute fields
SELECT a1.attrelid, a1.attname
FROM pg_attribute as a1
WHERE a1.attrelid = 0 OR a1.atttypid = 0 OR a1.attnum = 0 OR
a1.attcacheoff != -1 OR a1.attinhcount < 0 OR
(a1.attinhcount = 0 AND NOT a1.attislocal);
attrelid | attname
----------+---------
(0 rows)
-- Cross-check attnum against parent relation
SELECT a1.attrelid, a1.attname, c1.oid, c1.relname
FROM pg_attribute AS a1, pg_class AS c1
WHERE a1.attrelid = c1.oid AND a1.attnum > c1.relnatts;
attrelid | attname | oid | relname
----------+---------+-----+---------
(0 rows)
-- Detect missing pg_attribute entries: should have as many non-system
-- attributes as parent relation expects
SELECT c1.oid, c1.relname
FROM pg_class AS c1
WHERE c1.relnatts != (SELECT count(*) FROM pg_attribute AS a1
WHERE a1.attrelid = c1.oid AND a1.attnum > 0);
oid | relname
-----+---------
(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 a1.attrelid, a1.attname, t1.oid, t1.typname
FROM pg_attribute AS a1, pg_type AS t1
WHERE a1.atttypid = t1.oid AND
(a1.attlen != t1.typlen OR
a1.attalign != t1.typalign OR
a1.attbyval != t1.typbyval OR
(a1.attstorage != t1.typstorage AND a1.attstorage != 'p'));
attrelid | attname | oid | typname
----------+---------+-----+---------
(0 rows)
-- **************** pg_range ****************
-- Look for illegal values in pg_range fields.
SELECT r.rngtypid, r.rngsubtype
FROM pg_range as r
WHERE r.rngtypid = 0 OR r.rngsubtype = 0 OR r.rngsubopc = 0;
rngtypid | rngsubtype
----------+------------
(0 rows)
-- rngcollation should be specified iff subtype is collatable
SELECT r.rngtypid, r.rngsubtype, r.rngcollation, t.typcollation
FROM pg_range r JOIN pg_type t ON t.oid = r.rngsubtype
WHERE (rngcollation = 0) != (typcollation = 0);
rngtypid | rngsubtype | rngcollation | typcollation
----------+------------+--------------+--------------
(0 rows)
-- opclass had better be a btree opclass accepting the subtype.
Replace opr_sanity test's binary_coercible() function with C code. opr_sanity's binary_coercible() function has always been meant to match the parser's notion of binary coercibility, but it also has always been a rather poor approximation of the parser's real rules (as embodied in IsBinaryCoercible()). That hasn't bit us so far, but it's predictable that it will eventually. It also now emerges that implementing this check in plpgsql performs absolutely horribly in clobber-cache-always testing. (Perhaps we could do something about that, but I suspect it just means that plpgsql is exploiting catalog caching to the hilt.) Hence, let's replace binary_coercible() with a C shim that directly invokes IsBinaryCoercible(), eliminating both the semantic hazard and the performance issue. Most of regress.c's C functions are declared in create_function_1, but we can't simply move that to before opr_sanity/type_sanity since those tests would complain about the resulting shell types. I chose to split it into create_function_0 and create_function_1. Since create_function_0 now runs as part of a parallel group while create_function_1 doesn't, reduce the latter to create just those functions that opr_sanity and type_sanity would whine about. To make room for create_function_0 in the second parallel group of tests, move tstypes to the third parallel group. In passing, clean up some ordering deviations between parallel_schedule and serial_schedule. Discussion: https://postgr.es/m/292305.1620503097@sss.pgh.pa.us
2021-05-11 20:28:11 +02:00
-- We must allow anyarray matches, cf IsBinaryCoercible()
SELECT r.rngtypid, r.rngsubtype, o.opcmethod, o.opcname
FROM pg_range r JOIN pg_opclass o ON o.oid = r.rngsubopc
WHERE o.opcmethod != 403 OR
((o.opcintype != r.rngsubtype) AND NOT
(o.opcintype = 'pg_catalog.anyarray'::regtype AND
EXISTS(select 1 from pg_catalog.pg_type where
oid = r.rngsubtype and typelem != 0 and
Support subscripting of arbitrary types, not only arrays. This patch generalizes the subscripting infrastructure so that any data type can be subscripted, if it provides a handler function to define what that means. Traditional variable-length (varlena) arrays all use array_subscript_handler(), while the existing fixed-length types that support subscripting use raw_array_subscript_handler(). It's expected that other types that want to use subscripting notation will define their own handlers. (This patch provides no such new features, though; it only lays the foundation for them.) To do this, move the parser's semantic processing of subscripts (including coercion to whatever data type is required) into a method callback supplied by the handler. On the execution side, replace the ExecEvalSubscriptingRef* layer of functions with direct calls to callback-supplied execution routines. (Thus, essentially no new run-time overhead should be caused by this patch. Indeed, there is room to remove some overhead by supplying specialized execution routines. This patch does a little bit in that line, but more could be done.) Additional work is required here and there to remove formerly hard-wired assumptions about the result type, collation, etc of a SubscriptingRef expression node; and to remove assumptions that the subscript values must be integers. One useful side-effect of this is that we now have a less squishy mechanism for identifying whether a data type is a "true" array: instead of wiring in weird rules about typlen, we can look to see if pg_type.typsubscript == F_ARRAY_SUBSCRIPT_HANDLER. For this to be bulletproof, we have to forbid user-defined types from using that handler directly; but there seems no good reason for them to do so. This patch also removes assumptions that the number of subscripts is limited to MAXDIM (6), or indeed has any hard-wired limit. That limit still applies to types handled by array_subscript_handler or raw_array_subscript_handler, but to discourage other dependencies on this constant, I've moved it from c.h to utils/array.h. Dmitry Dolgov, reviewed at various times by Tom Lane, Arthur Zakirov, Peter Eisentraut, Pavel Stehule Discussion: https://postgr.es/m/CA+q6zcVDuGBv=M0FqBYX8DPebS3F_0KQ6OVFobGJPM507_SZ_w@mail.gmail.com Discussion: https://postgr.es/m/CA+q6zcVovR+XY4mfk-7oNk-rF91gH0PebnNfuUjuuDsyHjOcVA@mail.gmail.com
2020-12-09 18:40:37 +01:00
typsubscript = 'array_subscript_handler'::regproc)));
rngtypid | rngsubtype | opcmethod | opcname
----------+------------+-----------+---------
(0 rows)
-- canonical function, if any, had better match the range type
SELECT r.rngtypid, r.rngsubtype, p.proname
FROM pg_range r JOIN pg_proc p ON p.oid = r.rngcanonical
WHERE pronargs != 1 OR proargtypes[0] != rngtypid OR prorettype != rngtypid;
rngtypid | rngsubtype | proname
----------+------------+---------
(0 rows)
-- subdiff function, if any, had better match the subtype
SELECT r.rngtypid, r.rngsubtype, p.proname
FROM pg_range r JOIN pg_proc p ON p.oid = r.rngsubdiff
WHERE pronargs != 2
OR proargtypes[0] != rngsubtype OR proargtypes[1] != rngsubtype
OR prorettype != 'pg_catalog.float8'::regtype;
rngtypid | rngsubtype | proname
----------+------------+---------
(0 rows)
2020-12-20 05:20:33 +01:00
-- every range should have a valid multirange
SELECT r.rngtypid, r.rngsubtype, r.rngmultitypid
FROM pg_range r
WHERE r.rngmultitypid IS NULL OR r.rngmultitypid = 0;
2020-12-20 05:20:33 +01:00
rngtypid | rngsubtype | rngmultitypid
----------+------------+---------------
(0 rows)
-- 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.
CREATE TABLE tab_core_types AS SELECT
'(11,12)'::point,
'(1,1),(2,2)'::line,
'((11,11),(12,12))'::lseg,
'((11,11),(13,13))'::box,
'((11,12),(13,13),(14,14))'::path AS openedpath,
'[(11,12),(13,13),(14,14)]'::path AS closedpath,
'((11,12),(13,13),(14,14))'::polygon,
'1,1,1'::circle,
'today'::date,
'now'::time,
'now'::timestamp,
'now'::timetz,
'now'::timestamptz,
'12 seconds'::interval,
'{"reason":"because"}'::json,
'{"when":"now"}'::jsonb,
'$.a[*] ? (@ > 2)'::jsonpath,
'127.0.0.1'::inet,
'127.0.0.0/8'::cidr,
'00:01:03:86:1c:ba'::macaddr8,
'00:01:03:86:1c:ba'::macaddr,
2::int2, 4::int4, 8::int8,
4::float4, '8'::float8, pi()::numeric,
'foo'::"char",
'c'::bpchar,
'abc'::varchar,
'name'::name,
'txt'::text,
true::bool,
E'\\xDEADBEEF'::bytea,
B'10001'::bit,
B'10001'::varbit AS varbit,
'12.34'::money,
'abc'::refcursor,
'1 2'::int2vector,
'1 2'::oidvector,
format('%I=UC/%I', USER, USER)::aclitem AS aclitem,
'a fat cat sat on a mat and ate a fat rat'::tsvector,
'fat & rat'::tsquery,
'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid,
'11'::xid8,
'pg_class'::regclass,
'regtype'::regtype type,
'pg_monitor'::regrole,
'pg_class'::regclass::oid,
'(1,1)'::tid, '2'::xid, '3'::cid,
'10:20:10,14,15'::txid_snapshot,
'10:20:10,14,15'::pg_snapshot,
'16/B374D848'::pg_lsn,
1::information_schema.cardinal_number,
'l'::information_schema.character_data,
'n'::information_schema.sql_identifier,
'now'::information_schema.time_stamp,
'YES'::information_schema.yes_or_no,
'(1,2)'::int4range, '{(1,2)}'::int4multirange,
'(3,4)'::int8range, '{(3,4)}'::int8multirange,
'(3,4)'::numrange, '{(3,4)}'::nummultirange,
'(2020-01-02, 2021-02-03)'::daterange,
'{(2020-01-02, 2021-02-03)}'::datemultirange,
'(2020-01-02 03:04:05, 2021-02-03 06:07:08)'::tsrange,
'{(2020-01-02 03:04:05, 2021-02-03 06:07:08)}'::tsmultirange,
'(2020-01-02 03:04:05, 2021-02-03 06:07:08)'::tstzrange,
'{(2020-01-02 03:04:05, 2021-02-03 06:07:08)}'::tstzmultirange;
-- Sanity check on the previous table, checking that all core types are
-- included in this table.
SELECT oid, typname, typtype, typelem, typarray
FROM pg_type t
WHERE oid < 16384 AND
-- Exclude pseudotypes and composite types.
typtype NOT IN ('p', 'c') AND
-- These reg* types cannot be pg_upgraded, so discard them.
oid != ALL(ARRAY['regproc', 'regprocedure', 'regoper',
'regoperator', 'regconfig', 'regdictionary',
'regnamespace', 'regcollation']::regtype[]) AND
-- Discard types that do not accept input values as these cannot be
-- tested easily.
-- Note: XML might be disabled at compile-time.
oid != ALL(ARRAY['gtsvector', 'pg_node_tree',
'pg_ndistinct', 'pg_dependencies', 'pg_mcv_list',
'pg_brin_bloom_summary',
'pg_brin_minmax_multi_summary', 'xml']::regtype[]) AND
-- Discard arrays.
NOT EXISTS (SELECT 1 FROM pg_type u WHERE u.typarray = t.oid)
-- Exclude everything from the table created above. This checks
-- that no in-core types are missing in tab_core_types.
AND NOT EXISTS (SELECT 1
FROM pg_attribute a
WHERE a.atttypid=t.oid AND
a.attnum > 0 AND
a.attrelid='tab_core_types'::regclass);
oid | typname | typtype | typelem | typarray
-----+---------+---------+---------+----------
(0 rows)