2000-01-05 07:06:23 +01:00
|
|
|
--
|
|
|
|
-- TYPE_SANITY
|
|
|
|
-- Sanity checks for common errors in making type-related system tables:
|
2011-11-17 00:21:34 +01:00
|
|
|
-- pg_type, pg_class, pg_attribute, pg_range.
|
2000-01-05 07:06:23 +01:00
|
|
|
--
|
|
|
|
-- 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 p1.oid, p1.typname
|
1999-03-28 04:06:23 +02:00
|
|
|
FROM pg_type as p1
|
2002-08-22 02:01:51 +02:00
|
|
|
WHERE p1.typnamespace = 0 OR
|
2002-08-24 17:00:47 +02:00
|
|
|
(p1.typlen <= 0 AND p1.typlen != -1 AND p1.typlen != -2) OR
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
(p1.typtype not in ('b', 'c', 'd', 'e', 'p', 'r', 'm')) OR
|
1999-03-28 04:06:23 +02:00
|
|
|
NOT p1.typisdefined OR
|
2002-08-22 02:01:51 +02:00
|
|
|
(p1.typalign not in ('c', 's', 'i', 'd')) OR
|
|
|
|
(p1.typstorage not in ('p', 'x', 'e', 'm'));
|
2000-01-05 07:06:23 +01:00
|
|
|
oid | typname
|
|
|
|
-----+---------
|
1999-03-28 04:06:23 +02:00
|
|
|
(0 rows)
|
|
|
|
|
2000-01-05 07:06:23 +01:00
|
|
|
-- Look for "pass by value" types that can't be passed by value.
|
|
|
|
SELECT p1.oid, p1.typname
|
1999-03-28 04:06:23 +02:00
|
|
|
FROM pg_type as p1
|
|
|
|
WHERE p1.typbyval AND
|
|
|
|
(p1.typlen != 1 OR p1.typalign != 'c') AND
|
|
|
|
(p1.typlen != 2 OR p1.typalign != 's') AND
|
2008-04-21 02:26:47 +02:00
|
|
|
(p1.typlen != 4 OR p1.typalign != 'i') AND
|
|
|
|
(p1.typlen != 8 OR p1.typalign != 'd');
|
2000-01-05 07:06:23 +01:00
|
|
|
oid | typname
|
|
|
|
-----+---------
|
1999-03-28 04:06:23 +02:00
|
|
|
(0 rows)
|
|
|
|
|
2002-04-25 04:56:56 +02:00
|
|
|
-- 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)
|
|
|
|
|
2000-01-05 07:06:23 +01:00
|
|
|
-- Look for complex types that do not have a typrelid entry,
|
|
|
|
-- or basic types that do.
|
|
|
|
SELECT p1.oid, p1.typname
|
1999-03-28 04:06:23 +02:00
|
|
|
FROM pg_type as p1
|
|
|
|
WHERE (p1.typtype = 'c' AND p1.typrelid = 0) OR
|
|
|
|
(p1.typtype != 'c' AND p1.typrelid != 0);
|
2000-01-05 07:06:23 +01:00
|
|
|
oid | typname
|
|
|
|
-----+---------
|
1999-03-28 04:06:23 +02:00
|
|
|
(0 rows)
|
|
|
|
|
2020-12-07 17:10:21 +01:00
|
|
|
-- 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.
|
2002-04-25 04:56:56 +02:00
|
|
|
SELECT p1.oid, p1.typname
|
|
|
|
FROM pg_type as p1
|
2020-12-07 17:10:21 +01:00
|
|
|
WHERE p1.typtype not in ('p') AND p1.typname NOT LIKE E'\\_%'
|
2011-11-19 00:23:55 +01:00
|
|
|
AND NOT EXISTS
|
2002-04-25 04:56:56 +02:00
|
|
|
(SELECT 1 FROM pg_type as p2
|
|
|
|
WHERE p2.typname = ('_' || p1.typname)::name AND
|
2020-12-07 17:10:21 +01:00
|
|
|
p2.typelem = p1.oid and p1.typarray = p2.oid)
|
|
|
|
ORDER BY p1.oid;
|
2021-03-26 13:35:29 +01:00
|
|
|
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
|
2017-04-06 00:00:42 +02:00
|
|
|
3402 | pg_dependencies
|
2021-03-26 13:35:29 +01:00
|
|
|
4600 | pg_brin_bloom_summary
|
Add support for multivariate MCV lists
Introduce a third extended statistic type, supported by the CREATE
STATISTICS command - MCV lists, a generalization of the statistic
already built and used for individual columns.
Compared to the already supported types (n-distinct coefficients and
functional dependencies), MCV lists are more complex, include column
values and allow estimation of much wider range of common clauses
(equality and inequality conditions, IS NULL, IS NOT NULL etc.).
Similarly to the other types, a new pseudo-type (pg_mcv_list) is used.
Author: Tomas Vondra
Reviewed-by: Dean Rasheed, David Rowley, Mark Dilger, Alvaro Herrera
Discussion: https://postgr.es/m/dfdac334-9cf2-2597-fb27-f0fb3753f435@2ndquadrant.com
2019-03-27 18:32:18 +01:00
|
|
|
5017 | pg_mcv_list
|
2021-03-26 13:35:29 +01:00
|
|
|
(5 rows)
|
2002-04-25 04:56:56 +02:00
|
|
|
|
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
|
2010-11-23 21:27:50 +01:00
|
|
|
SELECT p1.oid, p1.typname as basetype, p2.typname as arraytype,
|
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
|
|
|
p2.typsubscript
|
Support arrays of composite types, including the rowtypes of regular tables
and views (but not system catalogs, nor sequences or toast tables). Get rid
of the hardwired convention that a type's array type is named exactly "_type",
instead using a new column pg_type.typarray to provide the linkage. (It still
will be named "_type", though, except in odd corner cases such as
maximum-length type names.)
Along the way, make tracking of owner and schema dependencies for types more
uniform: a type directly created by the user has these dependencies, while a
table rowtype or auto-generated array type does not have them, but depends on
its parent object instead.
David Fetter, Andrew Dunstan, Tom Lane
2007-05-11 19:57:14 +02:00
|
|
|
FROM pg_type p1 LEFT JOIN pg_type p2 ON (p1.typarray = p2.oid)
|
|
|
|
WHERE p1.typarray <> 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
|
|
|
(p2.oid IS NULL OR
|
|
|
|
p2.typsubscript <> 'array_subscript_handler'::regproc);
|
|
|
|
oid | basetype | arraytype | typsubscript
|
|
|
|
-----+----------+-----------+--------------
|
Support arrays of composite types, including the rowtypes of regular tables
and views (but not system catalogs, nor sequences or toast tables). Get rid
of the hardwired convention that a type's array type is named exactly "_type",
instead using a new column pg_type.typarray to provide the linkage. (It still
will be named "_type", though, except in odd corner cases such as
maximum-length type names.)
Along the way, make tracking of owner and schema dependencies for types more
uniform: a type directly created by the user has these dependencies, while a
table rowtype or auto-generated array type does not have them, but depends on
its parent object instead.
David Fetter, Andrew Dunstan, Tom Lane
2007-05-11 19:57:14 +02:00
|
|
|
(0 rows)
|
|
|
|
|
2011-11-15 03:42:04 +01:00
|
|
|
-- Look for range types that do not have a pg_range entry
|
|
|
|
SELECT p1.oid, p1.typname
|
|
|
|
FROM pg_type as p1
|
|
|
|
WHERE p1.typtype = 'r' AND
|
|
|
|
NOT EXISTS(SELECT 1 FROM pg_range r WHERE rngtypid = p1.oid);
|
|
|
|
oid | typname
|
|
|
|
-----+---------
|
|
|
|
(0 rows)
|
|
|
|
|
|
|
|
-- Look for range types whose typalign isn't sufficient
|
|
|
|
SELECT p1.oid, p1.typname, p1.typalign, p2.typname, p2.typalign
|
|
|
|
FROM pg_type as p1
|
|
|
|
LEFT JOIN pg_range as r ON rngtypid = p1.oid
|
|
|
|
LEFT JOIN pg_type as p2 ON rngsubtype = p2.oid
|
|
|
|
WHERE p1.typtype = 'r' AND
|
|
|
|
(p1.typalign != (CASE WHEN p2.typalign = 'd' THEN 'd'::"char"
|
|
|
|
ELSE 'i'::"char" END)
|
|
|
|
OR p2.oid IS NULL);
|
|
|
|
oid | typname | typalign | typname | typalign
|
|
|
|
-----+---------+----------+---------+----------
|
|
|
|
(0 rows)
|
|
|
|
|
2005-07-10 23:14:00 +02:00
|
|
|
-- Text conversion routines must be provided.
|
2000-01-05 07:06:23 +01:00
|
|
|
SELECT p1.oid, p1.typname
|
1999-03-28 04:06:23 +02:00
|
|
|
FROM pg_type as p1
|
2005-07-10 23:14:00 +02:00
|
|
|
WHERE (p1.typinput = 0 OR p1.typoutput = 0);
|
2000-01-05 07:06:23 +01:00
|
|
|
oid | typname
|
|
|
|
-----+---------
|
1999-03-28 04:06:23 +02:00
|
|
|
(0 rows)
|
|
|
|
|
2000-01-05 07:06:23 +01:00
|
|
|
-- Check for bogus typinput routines
|
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
1999-03-28 04:06:23 +02:00
|
|
|
FROM pg_type AS p1, pg_proc AS p2
|
2013-02-13 22:20:01 +01:00
|
|
|
WHERE p1.typinput = p2.oid AND NOT
|
2002-08-22 02:01:51 +02:00
|
|
|
((p2.pronargs = 1 AND p2.proargtypes[0] = 'cstring'::regtype) OR
|
2013-02-13 22:20:01 +01:00
|
|
|
(p2.pronargs = 2 AND p2.proargtypes[0] = 'cstring'::regtype AND
|
|
|
|
p2.proargtypes[1] = 'oid'::regtype) OR
|
2002-08-22 02:01:51 +02:00
|
|
|
(p2.pronargs = 3 AND p2.proargtypes[0] = 'cstring'::regtype AND
|
|
|
|
p2.proargtypes[1] = 'oid'::regtype AND
|
|
|
|
p2.proargtypes[2] = 'int4'::regtype));
|
|
|
|
oid | typname | oid | proname
|
|
|
|
-----+---------+-----+---------
|
|
|
|
(0 rows)
|
|
|
|
|
2017-10-31 05:22:39 +01:00
|
|
|
-- Check for type of the variadic array parameter's elements.
|
|
|
|
-- provariadic should be ANYOID if the type of the last element is ANYOID,
|
Introduce "anycompatible" family of polymorphic types.
This patch adds the pseudo-types anycompatible, anycompatiblearray,
anycompatiblenonarray, and anycompatiblerange. They work much like
anyelement, anyarray, anynonarray, and anyrange respectively, except
that the actual input values need not match precisely in type.
Instead, if we can find a common supertype (using the same rules
as for UNION/CASE type resolution), then the parser automatically
promotes the input values to that type. For example,
"myfunc(anycompatible, anycompatible)" can match a call with one
integer and one bigint argument, with the integer automatically
promoted to bigint. With anyelement in the definition, the user
would have had to cast the integer explicitly.
The new types also provide a second, independent set of type variables
for function matching; thus with "myfunc(anyelement, anyelement,
anycompatible) returns anycompatible" the first two arguments are
constrained to be the same type, but the third can be some other
type, and the result has the type of the third argument. The need
for more than one set of type variables was foreseen back when we
first invented the polymorphic types, but we never did anything
about it.
Pavel Stehule, revised a bit by me
Discussion: https://postgr.es/m/CAFj8pRDna7VqNi8gR+Tt2Ktmz0cq5G93guc3Sbn_NVPLdXAkqA@mail.gmail.com
2020-03-19 16:43:11 +01:00
|
|
|
-- ANYELEMENTOID if the type of the last element is ANYARRAYOID,
|
|
|
|
-- ANYCOMPATIBLEOID if the type of the last element is ANYCOMPATIBLEARRAYOID,
|
|
|
|
-- and otherwise the element type corresponding to the array type.
|
2017-10-31 05:22:39 +01:00
|
|
|
SELECT oid::regprocedure, provariadic::regtype, proargtypes::regtype[]
|
|
|
|
FROM pg_proc
|
|
|
|
WHERE provariadic != 0
|
|
|
|
AND case proargtypes[array_length(proargtypes, 1)-1]
|
Introduce "anycompatible" family of polymorphic types.
This patch adds the pseudo-types anycompatible, anycompatiblearray,
anycompatiblenonarray, and anycompatiblerange. They work much like
anyelement, anyarray, anynonarray, and anyrange respectively, except
that the actual input values need not match precisely in type.
Instead, if we can find a common supertype (using the same rules
as for UNION/CASE type resolution), then the parser automatically
promotes the input values to that type. For example,
"myfunc(anycompatible, anycompatible)" can match a call with one
integer and one bigint argument, with the integer automatically
promoted to bigint. With anyelement in the definition, the user
would have had to cast the integer explicitly.
The new types also provide a second, independent set of type variables
for function matching; thus with "myfunc(anyelement, anyelement,
anycompatible) returns anycompatible" the first two arguments are
constrained to be the same type, but the third can be some other
type, and the result has the type of the third argument. The need
for more than one set of type variables was foreseen back when we
first invented the polymorphic types, but we never did anything
about it.
Pavel Stehule, revised a bit by me
Discussion: https://postgr.es/m/CAFj8pRDna7VqNi8gR+Tt2Ktmz0cq5G93guc3Sbn_NVPLdXAkqA@mail.gmail.com
2020-03-19 16:43:11 +01:00
|
|
|
WHEN '"any"'::regtype THEN '"any"'::regtype
|
|
|
|
WHEN 'anyarray'::regtype THEN 'anyelement'::regtype
|
|
|
|
WHEN 'anycompatiblearray'::regtype THEN 'anycompatible'::regtype
|
2017-10-31 05:22:39 +01:00
|
|
|
ELSE (SELECT t.oid
|
|
|
|
FROM pg_type t
|
|
|
|
WHERE t.typarray = proargtypes[array_length(proargtypes, 1)-1])
|
|
|
|
END != provariadic;
|
|
|
|
oid | provariadic | proargtypes
|
|
|
|
-----+-------------+-------------
|
|
|
|
(0 rows)
|
|
|
|
|
2017-11-17 17:53:00 +01:00
|
|
|
-- Check that all and only those functions with a variadic type have
|
|
|
|
-- a variadic argument.
|
|
|
|
SELECT oid::regprocedure, proargmodes, provariadic
|
|
|
|
FROM pg_proc
|
|
|
|
WHERE (proargmodes IS NOT NULL AND 'v' = any(proargmodes))
|
|
|
|
IS DISTINCT FROM
|
|
|
|
(provariadic != 0);
|
|
|
|
oid | proargmodes | provariadic
|
|
|
|
-----+-------------+-------------
|
|
|
|
(0 rows)
|
|
|
|
|
2004-08-04 23:34:35 +02:00
|
|
|
-- As of 8.0, this check finds refcursor, which is borrowing
|
2002-08-22 02:01:51 +02:00
|
|
|
-- other types' I/O routines
|
|
|
|
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 in ('b', 'p') AND NOT
|
|
|
|
(p1.typelem != 0 AND p1.typlen < 0) AND NOT
|
2003-01-15 20:35:48 +01:00
|
|
|
(p2.prorettype = p1.oid AND NOT p2.proretset)
|
|
|
|
ORDER BY 1;
|
2004-06-06 21:07:02 +02:00
|
|
|
oid | typname | oid | proname
|
|
|
|
------+-----------+-----+---------
|
2002-08-22 02:01:51 +02:00
|
|
|
1790 | refcursor | 46 | textin
|
2004-06-06 21:07:02 +02:00
|
|
|
(1 row)
|
2002-08-22 02:01:51 +02:00
|
|
|
|
|
|
|
-- Varlena array types will point to array_in
|
2005-03-29 02:17:27 +02:00
|
|
|
-- Exception as of 8.1: int2vector and oidvector have their own I/O routines
|
2002-08-22 02:01:51 +02:00
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
|
|
|
FROM pg_type AS p1, pg_proc AS p2
|
2013-02-13 22:20:01 +01:00
|
|
|
WHERE p1.typinput = p2.oid AND
|
2002-08-22 02:01:51 +02:00
|
|
|
(p1.typelem != 0 AND p1.typlen < 0) AND NOT
|
2005-03-29 02:17:27 +02:00
|
|
|
(p2.oid = 'array_in'::regproc)
|
|
|
|
ORDER BY 1;
|
|
|
|
oid | typname | oid | proname
|
|
|
|
-----+------------+-----+--------------
|
|
|
|
22 | int2vector | 40 | int2vectorin
|
|
|
|
30 | oidvector | 54 | oidvectorin
|
|
|
|
(2 rows)
|
1999-03-28 04:06:23 +02:00
|
|
|
|
2014-10-23 21:59:40 +02:00
|
|
|
-- typinput routines should not be volatile
|
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
|
|
|
FROM pg_type AS p1, pg_proc AS p2
|
|
|
|
WHERE p1.typinput = p2.oid AND p2.provolatile NOT IN ('i', 's');
|
|
|
|
oid | typname | oid | proname
|
|
|
|
-----+---------+-----+---------
|
|
|
|
(0 rows)
|
|
|
|
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
-- Composites, domains, enums, multiranges, ranges should all use the same input routines
|
2011-11-19 00:23:55 +01:00
|
|
|
SELECT DISTINCT typtype, typinput
|
|
|
|
FROM pg_type AS p1
|
|
|
|
WHERE p1.typtype not in ('b', 'p')
|
|
|
|
ORDER BY 1;
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
typtype | typinput
|
|
|
|
---------+---------------
|
2011-11-19 00:23:55 +01:00
|
|
|
c | record_in
|
|
|
|
d | domain_in
|
|
|
|
e | enum_in
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
m | multirange_in
|
2011-11-19 00:23:55 +01:00
|
|
|
r | range_in
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
(5 rows)
|
2011-11-19 00:23:55 +01:00
|
|
|
|
2000-01-05 07:06:23 +01:00
|
|
|
-- Check for bogus typoutput routines
|
2004-08-04 23:34:35 +02:00
|
|
|
-- As of 8.0, this check finds refcursor, which is borrowing
|
2002-08-22 02:01:51 +02:00
|
|
|
-- other types' I/O routines
|
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
|
|
|
FROM pg_type AS p1, pg_proc AS p2
|
|
|
|
WHERE p1.typoutput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
2005-04-30 22:31:39 +02:00
|
|
|
(p2.pronargs = 1 AND
|
|
|
|
(p2.proargtypes[0] = p1.oid OR
|
|
|
|
(p2.oid = 'array_out'::regproc AND
|
|
|
|
p1.typelem != 0 AND p1.typlen = -1)))
|
2003-01-15 20:35:48 +01:00
|
|
|
ORDER BY 1;
|
2004-06-06 21:07:02 +02:00
|
|
|
oid | typname | oid | proname
|
|
|
|
------+-----------+-----+---------
|
2002-08-22 02:01:51 +02:00
|
|
|
1790 | refcursor | 47 | textout
|
2004-06-06 21:07:02 +02:00
|
|
|
(1 row)
|
2002-08-22 02:01:51 +02:00
|
|
|
|
2000-01-05 07:06:23 +01:00
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
1999-03-28 04:06:23 +02:00
|
|
|
FROM pg_type AS p1, pg_proc AS p2
|
2013-02-13 22:20:01 +01:00
|
|
|
WHERE p1.typoutput = p2.oid AND NOT
|
2002-08-22 02:01:51 +02:00
|
|
|
(p2.prorettype = 'cstring'::regtype AND NOT p2.proretset);
|
2003-05-09 00:19:58 +02:00
|
|
|
oid | typname | oid | proname
|
|
|
|
-----+---------+-----+---------
|
|
|
|
(0 rows)
|
|
|
|
|
2014-10-23 21:59:40 +02:00
|
|
|
-- typoutput routines should not be volatile
|
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
|
|
|
FROM pg_type AS p1, pg_proc AS p2
|
|
|
|
WHERE p1.typoutput = p2.oid AND p2.provolatile NOT IN ('i', 's');
|
|
|
|
oid | typname | oid | proname
|
|
|
|
-----+---------+-----+---------
|
|
|
|
(0 rows)
|
|
|
|
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
-- Composites, enums, multiranges, ranges should all use the same output routines
|
2011-11-19 00:23:55 +01:00
|
|
|
SELECT DISTINCT typtype, typoutput
|
|
|
|
FROM pg_type AS p1
|
|
|
|
WHERE p1.typtype not in ('b', 'd', 'p')
|
|
|
|
ORDER BY 1;
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
typtype | typoutput
|
|
|
|
---------+----------------
|
2011-11-19 00:23:55 +01:00
|
|
|
c | record_out
|
|
|
|
e | enum_out
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
m | multirange_out
|
2011-11-19 00:23:55 +01:00
|
|
|
r | range_out
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
(4 rows)
|
2011-11-19 00:23:55 +01:00
|
|
|
|
|
|
|
-- 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)
|
|
|
|
|
2003-05-09 00:19:58 +02:00
|
|
|
-- Check for bogus typreceive routines
|
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
|
|
|
FROM pg_type AS p1, pg_proc AS p2
|
2013-02-13 22:20:01 +01:00
|
|
|
WHERE p1.typreceive = p2.oid AND NOT
|
2003-05-10 01:01:45 +02:00
|
|
|
((p2.pronargs = 1 AND p2.proargtypes[0] = 'internal'::regtype) OR
|
2013-02-13 22:20:01 +01:00
|
|
|
(p2.pronargs = 2 AND p2.proargtypes[0] = 'internal'::regtype AND
|
|
|
|
p2.proargtypes[1] = 'oid'::regtype) OR
|
2005-07-10 23:14:00 +02:00
|
|
|
(p2.pronargs = 3 AND p2.proargtypes[0] = 'internal'::regtype AND
|
|
|
|
p2.proargtypes[1] = 'oid'::regtype AND
|
|
|
|
p2.proargtypes[2] = 'int4'::regtype));
|
2003-05-09 00:19:58 +02:00
|
|
|
oid | typname | oid | proname
|
|
|
|
-----+---------+-----+---------
|
|
|
|
(0 rows)
|
|
|
|
|
2003-05-09 17:44:42 +02:00
|
|
|
-- As of 7.4, this check finds refcursor, which is borrowing
|
|
|
|
-- other types' I/O routines
|
2003-05-09 00:19:58 +02:00
|
|
|
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 in ('b', 'p') AND NOT
|
|
|
|
(p1.typelem != 0 AND p1.typlen < 0) AND NOT
|
2003-05-09 17:44:42 +02:00
|
|
|
(p2.prorettype = p1.oid AND NOT p2.proretset)
|
|
|
|
ORDER BY 1;
|
|
|
|
oid | typname | oid | proname
|
|
|
|
------+-----------+------+----------
|
|
|
|
1790 | refcursor | 2414 | textrecv
|
|
|
|
(1 row)
|
2003-05-09 00:19:58 +02:00
|
|
|
|
|
|
|
-- Varlena array types will point to array_recv
|
2005-03-29 02:17:27 +02:00
|
|
|
-- Exception as of 8.1: int2vector and oidvector have their own I/O routines
|
2003-05-09 00:19:58 +02:00
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
|
|
|
FROM pg_type AS p1, pg_proc AS p2
|
2013-02-13 22:20:01 +01:00
|
|
|
WHERE p1.typreceive = p2.oid AND
|
2003-05-09 00:19:58 +02:00
|
|
|
(p1.typelem != 0 AND p1.typlen < 0) AND NOT
|
2005-03-29 02:17:27 +02:00
|
|
|
(p2.oid = 'array_recv'::regproc)
|
|
|
|
ORDER BY 1;
|
|
|
|
oid | typname | oid | proname
|
|
|
|
-----+------------+------+----------------
|
|
|
|
22 | int2vector | 2410 | int2vectorrecv
|
|
|
|
30 | oidvector | 2420 | oidvectorrecv
|
|
|
|
(2 rows)
|
2003-05-09 00:19:58 +02:00
|
|
|
|
2005-07-10 23:14:00 +02:00
|
|
|
-- Suspicious if typreceive doesn't take same number of args as typinput
|
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname, p3.oid, p3.proname
|
|
|
|
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;
|
|
|
|
oid | typname | oid | proname | oid | proname
|
|
|
|
-----+---------+-----+---------+-----+---------
|
|
|
|
(0 rows)
|
|
|
|
|
2014-10-23 21:59:40 +02:00
|
|
|
-- typreceive routines should not be volatile
|
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
|
|
|
FROM pg_type AS p1, pg_proc AS p2
|
|
|
|
WHERE p1.typreceive = p2.oid AND p2.provolatile NOT IN ('i', 's');
|
|
|
|
oid | typname | oid | proname
|
|
|
|
-----+---------+-----+---------
|
|
|
|
(0 rows)
|
|
|
|
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
-- Composites, domains, enums, multiranges, ranges should all use the same receive routines
|
2011-11-19 00:23:55 +01:00
|
|
|
SELECT DISTINCT typtype, typreceive
|
|
|
|
FROM pg_type AS p1
|
|
|
|
WHERE p1.typtype not in ('b', 'p')
|
|
|
|
ORDER BY 1;
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
typtype | typreceive
|
|
|
|
---------+-----------------
|
2011-11-19 00:23:55 +01:00
|
|
|
c | record_recv
|
|
|
|
d | domain_recv
|
|
|
|
e | enum_recv
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
m | multirange_recv
|
2011-11-19 00:23:55 +01:00
|
|
|
r | range_recv
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
(5 rows)
|
2011-11-19 00:23:55 +01:00
|
|
|
|
2003-05-09 00:19:58 +02:00
|
|
|
-- Check for bogus typsend routines
|
2003-05-09 17:44:42 +02:00
|
|
|
-- As of 7.4, this check finds refcursor, which is borrowing
|
|
|
|
-- other types' I/O routines
|
2003-05-09 00:19:58 +02:00
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
|
|
|
FROM pg_type AS p1, pg_proc AS p2
|
|
|
|
WHERE p1.typsend = p2.oid AND p1.typtype in ('b', 'p') AND NOT
|
2005-04-30 22:31:39 +02:00
|
|
|
(p2.pronargs = 1 AND
|
|
|
|
(p2.proargtypes[0] = p1.oid OR
|
|
|
|
(p2.oid = 'array_send'::regproc AND
|
|
|
|
p1.typelem != 0 AND p1.typlen = -1)))
|
2003-05-09 17:44:42 +02:00
|
|
|
ORDER BY 1;
|
|
|
|
oid | typname | oid | proname
|
|
|
|
------+-----------+------+----------
|
|
|
|
1790 | refcursor | 2415 | textsend
|
|
|
|
(1 row)
|
2003-05-09 00:19:58 +02:00
|
|
|
|
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
|
|
|
FROM pg_type AS p1, pg_proc AS p2
|
2013-02-13 22:20:01 +01:00
|
|
|
WHERE p1.typsend = p2.oid AND NOT
|
2003-05-09 00:19:58 +02:00
|
|
|
(p2.prorettype = 'bytea'::regtype AND NOT p2.proretset);
|
2006-12-30 22:21:56 +01:00
|
|
|
oid | typname | oid | proname
|
|
|
|
-----+---------+-----+---------
|
|
|
|
(0 rows)
|
|
|
|
|
2014-10-23 21:59:40 +02:00
|
|
|
-- typsend routines should not be volatile
|
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
|
|
|
FROM pg_type AS p1, pg_proc AS p2
|
|
|
|
WHERE p1.typsend = p2.oid AND p2.provolatile NOT IN ('i', 's');
|
|
|
|
oid | typname | oid | proname
|
|
|
|
-----+---------+-----+---------
|
|
|
|
(0 rows)
|
|
|
|
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
-- Composites, enums, multiranges, ranges should all use the same send routines
|
2011-11-19 00:23:55 +01:00
|
|
|
SELECT DISTINCT typtype, typsend
|
|
|
|
FROM pg_type AS p1
|
|
|
|
WHERE p1.typtype not in ('b', 'd', 'p')
|
|
|
|
ORDER BY 1;
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
typtype | typsend
|
|
|
|
---------+-----------------
|
2011-11-19 00:23:55 +01:00
|
|
|
c | record_send
|
|
|
|
e | enum_send
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
m | multirange_send
|
2011-11-19 00:23:55 +01:00
|
|
|
r | range_send
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
(4 rows)
|
2011-11-19 00:23:55 +01:00
|
|
|
|
|
|
|
-- 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)
|
|
|
|
|
2006-12-30 22:21:56 +01:00
|
|
|
-- Check for bogus typmodin routines
|
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
|
|
|
FROM pg_type AS p1, pg_proc AS p2
|
2011-11-19 00:23:55 +01:00
|
|
|
WHERE p1.typmodin = p2.oid AND NOT
|
2006-12-30 22:21:56 +01:00
|
|
|
(p2.pronargs = 1 AND
|
2007-06-15 22:56:52 +02:00
|
|
|
p2.proargtypes[0] = 'cstring[]'::regtype AND
|
2006-12-30 22:21:56 +01:00
|
|
|
p2.prorettype = 'int4'::regtype AND NOT p2.proretset);
|
|
|
|
oid | typname | oid | proname
|
|
|
|
-----+---------+-----+---------
|
|
|
|
(0 rows)
|
|
|
|
|
2014-10-23 21:59:40 +02:00
|
|
|
-- typmodin routines should not be volatile
|
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
|
|
|
FROM pg_type AS p1, pg_proc AS p2
|
|
|
|
WHERE p1.typmodin = p2.oid AND p2.provolatile NOT IN ('i', 's');
|
|
|
|
oid | typname | oid | proname
|
|
|
|
-----+---------+-----+---------
|
|
|
|
(0 rows)
|
|
|
|
|
2006-12-30 22:21:56 +01:00
|
|
|
-- Check for bogus typmodout routines
|
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
|
|
|
FROM pg_type AS p1, pg_proc AS p2
|
2011-11-19 00:23:55 +01:00
|
|
|
WHERE p1.typmodout = p2.oid AND NOT
|
2006-12-30 22:21:56 +01:00
|
|
|
(p2.pronargs = 1 AND
|
|
|
|
p2.proargtypes[0] = 'int4'::regtype AND
|
|
|
|
p2.prorettype = 'cstring'::regtype AND NOT p2.proretset);
|
|
|
|
oid | typname | oid | proname
|
|
|
|
-----+---------+-----+---------
|
|
|
|
(0 rows)
|
|
|
|
|
2014-10-23 21:59:40 +02:00
|
|
|
-- typmodout routines should not be volatile
|
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
|
|
|
FROM pg_type AS p1, pg_proc AS p2
|
|
|
|
WHERE p1.typmodout = p2.oid AND p2.provolatile NOT IN ('i', 's');
|
|
|
|
oid | typname | oid | proname
|
|
|
|
-----+---------+-----+---------
|
|
|
|
(0 rows)
|
|
|
|
|
2006-12-30 22:21:56 +01:00
|
|
|
-- Array types should have same typmodin/out as their element types
|
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.typname
|
|
|
|
FROM pg_type AS p1, pg_type AS p2
|
|
|
|
WHERE p1.typelem = p2.oid AND NOT
|
|
|
|
(p1.typmodin = p2.typmodin AND p1.typmodout = p2.typmodout);
|
|
|
|
oid | typname | oid | typname
|
|
|
|
-----+---------+-----+---------
|
|
|
|
(0 rows)
|
|
|
|
|
2008-09-25 05:28:56 +02:00
|
|
|
-- Array types should have same typdelim as their element types
|
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.typname
|
|
|
|
FROM pg_type AS p1, pg_type AS p2
|
|
|
|
WHERE p1.typarray = p2.oid AND NOT (p1.typdelim = p2.typdelim);
|
|
|
|
oid | typname | oid | typname
|
|
|
|
-----+---------+-----+---------
|
|
|
|
(0 rows)
|
|
|
|
|
2011-11-15 03:42:04 +01:00
|
|
|
-- Look for array types whose typalign isn't sufficient
|
|
|
|
SELECT p1.oid, p1.typname, p1.typalign, p2.typname, p2.typalign
|
|
|
|
FROM pg_type AS p1, pg_type AS p2
|
|
|
|
WHERE p1.typarray = p2.oid AND
|
|
|
|
p2.typalign != (CASE WHEN p1.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 p1.oid, p1.typname, p1.typelem
|
|
|
|
FROM pg_type AS p1
|
|
|
|
WHERE p1.typelem != 0 AND p1.typsubscript = 0;
|
|
|
|
oid | typname | typelem
|
|
|
|
-----+---------+---------
|
|
|
|
(0 rows)
|
|
|
|
|
|
|
|
-- Check for misuse of standard subscript handlers
|
|
|
|
SELECT p1.oid, p1.typname,
|
|
|
|
p1.typelem, p1.typlen, p1.typbyval
|
|
|
|
FROM pg_type AS p1
|
|
|
|
WHERE p1.typsubscript = 'array_subscript_handler'::regproc AND NOT
|
|
|
|
(p1.typelem != 0 AND p1.typlen = -1 AND NOT p1.typbyval);
|
|
|
|
oid | typname | typelem | typlen | typbyval
|
|
|
|
-----+---------+---------+--------+----------
|
|
|
|
(0 rows)
|
|
|
|
|
|
|
|
SELECT p1.oid, p1.typname,
|
|
|
|
p1.typelem, p1.typlen, p1.typbyval
|
|
|
|
FROM pg_type AS p1
|
|
|
|
WHERE p1.typsubscript = 'raw_array_subscript_handler'::regproc AND NOT
|
|
|
|
(p1.typelem != 0 AND p1.typlen > 0 AND NOT p1.typbyval);
|
|
|
|
oid | typname | typelem | typlen | typbyval
|
|
|
|
-----+---------+---------+--------+----------
|
|
|
|
(0 rows)
|
|
|
|
|
2006-12-30 22:21:56 +01:00
|
|
|
-- Check for bogus typanalyze routines
|
|
|
|
SELECT p1.oid, p1.typname, p2.oid, p2.proname
|
|
|
|
FROM pg_type AS p1, pg_proc AS p2
|
2011-11-19 00:23:55 +01:00
|
|
|
WHERE p1.typanalyze = p2.oid AND NOT
|
2006-12-30 22:21:56 +01:00
|
|
|
(p2.pronargs = 1 AND
|
|
|
|
p2.proargtypes[0] = 'internal'::regtype AND
|
|
|
|
p2.prorettype = 'bool'::regtype AND NOT p2.proretset);
|
2000-01-05 07:06:23 +01:00
|
|
|
oid | typname | oid | proname
|
|
|
|
-----+---------+-----+---------
|
1999-03-28 04:06:23 +02:00
|
|
|
(0 rows)
|
|
|
|
|
2014-10-23 21:59:40 +02:00
|
|
|
-- there does not seem to be a reason to care about volatility of typanalyze
|
2012-03-04 02:20:19 +01:00
|
|
|
-- 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)
|
2012-03-04 02:20:19 +01:00
|
|
|
ORDER BY 1;
|
|
|
|
oid | typname | typanalyze
|
|
|
|
-----+------------+------------
|
|
|
|
22 | int2vector | -
|
|
|
|
30 | oidvector | -
|
|
|
|
(2 rows)
|
|
|
|
|
2000-01-05 07:06:23 +01:00
|
|
|
-- **************** pg_class ****************
|
|
|
|
-- Look for illegal values in pg_class fields
|
|
|
|
SELECT p1.oid, p1.relname
|
1999-03-28 04:06:23 +02:00
|
|
|
FROM pg_class as p1
|
2017-03-10 19:15:47 +01:00
|
|
|
WHERE relkind NOT IN ('r', 'i', 'S', 't', 'v', 'm', 'c', 'f', 'p') OR
|
2016-01-09 23:20:58 +01:00
|
|
|
relpersistence NOT IN ('p', 'u', 't') OR
|
|
|
|
relreplident NOT IN ('d', 'n', 'f', 'i');
|
2000-01-05 07:06:23 +01:00
|
|
|
oid | relname
|
|
|
|
-----+---------
|
1999-03-28 04:06:23 +02:00
|
|
|
(0 rows)
|
|
|
|
|
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
|
|
|
-- All tables and indexes should have an access method.
|
2000-01-05 07:06:23 +01:00
|
|
|
SELECT p1.oid, p1.relname
|
1999-03-28 04:06:23 +02:00
|
|
|
FROM pg_class as p1
|
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
|
|
|
WHERE p1.relkind NOT IN ('S', 'v', 'f', 'c') and
|
|
|
|
p1.relam = 0;
|
|
|
|
oid | relname
|
|
|
|
-----+---------
|
|
|
|
(0 rows)
|
|
|
|
|
|
|
|
-- Conversely, sequences, views, types shouldn't have them
|
|
|
|
SELECT p1.oid, p1.relname
|
|
|
|
FROM pg_class as p1
|
|
|
|
WHERE p1.relkind IN ('S', 'v', 'f', 'c') and
|
|
|
|
p1.relam != 0;
|
2000-01-05 07:06:23 +01:00
|
|
|
oid | relname
|
|
|
|
-----+---------
|
1999-03-28 04:06:23 +02:00
|
|
|
(0 rows)
|
|
|
|
|
2019-04-05 02:17:50 +02:00
|
|
|
-- 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') 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)
|
|
|
|
|
2000-01-05 07:06:23 +01:00
|
|
|
-- **************** pg_attribute ****************
|
|
|
|
-- Look for illegal values in pg_attribute fields
|
2001-08-10 20:57:42 +02:00
|
|
|
SELECT p1.attrelid, p1.attname
|
1999-03-28 04:06:23 +02:00
|
|
|
FROM pg_attribute as p1
|
|
|
|
WHERE p1.attrelid = 0 OR p1.atttypid = 0 OR p1.attnum = 0 OR
|
2002-09-22 21:42:52 +02:00
|
|
|
p1.attcacheoff != -1 OR p1.attinhcount < 0 OR
|
|
|
|
(p1.attinhcount = 0 AND NOT p1.attislocal);
|
2001-08-10 20:57:42 +02:00
|
|
|
attrelid | attname
|
|
|
|
----------+---------
|
1999-03-28 04:06:23 +02:00
|
|
|
(0 rows)
|
|
|
|
|
2000-01-05 07:06:23 +01:00
|
|
|
-- Cross-check attnum against parent relation
|
2001-08-10 20:57:42 +02:00
|
|
|
SELECT p1.attrelid, p1.attname, p2.oid, p2.relname
|
1999-03-28 04:06:23 +02:00
|
|
|
FROM pg_attribute AS p1, pg_class AS p2
|
|
|
|
WHERE p1.attrelid = p2.oid AND p1.attnum > p2.relnatts;
|
2001-08-10 20:57:42 +02:00
|
|
|
attrelid | attname | oid | relname
|
|
|
|
----------+---------+-----+---------
|
1999-03-28 04:06:23 +02:00
|
|
|
(0 rows)
|
|
|
|
|
2000-01-05 07:06:23 +01:00
|
|
|
-- Detect missing pg_attribute entries: should have as many non-system
|
|
|
|
-- attributes as parent relation expects
|
|
|
|
SELECT p1.oid, p1.relname
|
1999-03-28 04:06:23 +02:00
|
|
|
FROM pg_class AS p1
|
|
|
|
WHERE p1.relnatts != (SELECT count(*) FROM pg_attribute AS p2
|
|
|
|
WHERE p2.attrelid = p1.oid AND p2.attnum > 0);
|
2000-01-05 07:06:23 +01:00
|
|
|
oid | relname
|
|
|
|
-----+---------
|
1999-03-28 04:06:23 +02:00
|
|
|
(0 rows)
|
|
|
|
|
2000-01-05 07:06:23 +01:00
|
|
|
-- Cross-check against pg_type entry
|
2002-04-25 04:56:56 +02:00
|
|
|
-- NOTE: we allow attstorage to be 'plain' even when typstorage is not;
|
|
|
|
-- this is mainly for toast tables.
|
2001-08-10 20:57:42 +02:00
|
|
|
SELECT p1.attrelid, p1.attname, p2.oid, p2.typname
|
1999-03-28 04:06:23 +02:00
|
|
|
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
|
2002-04-25 04:56:56 +02:00
|
|
|
p1.attbyval != p2.typbyval OR
|
|
|
|
(p1.attstorage != p2.typstorage AND p1.attstorage != 'p'));
|
2001-08-10 20:57:42 +02:00
|
|
|
attrelid | attname | oid | typname
|
|
|
|
----------+---------+-----+---------
|
1999-03-28 04:06:23 +02:00
|
|
|
(0 rows)
|
|
|
|
|
2011-11-17 00:21:34 +01:00
|
|
|
-- **************** pg_range ****************
|
|
|
|
-- Look for illegal values in pg_range fields.
|
|
|
|
SELECT p1.rngtypid, p1.rngsubtype
|
|
|
|
FROM pg_range as p1
|
|
|
|
WHERE p1.rngtypid = 0 OR p1.rngsubtype = 0 OR p1.rngsubopc = 0;
|
|
|
|
rngtypid | rngsubtype
|
|
|
|
----------+------------
|
|
|
|
(0 rows)
|
|
|
|
|
|
|
|
-- rngcollation should be specified iff subtype is collatable
|
|
|
|
SELECT p1.rngtypid, p1.rngsubtype, p1.rngcollation, t.typcollation
|
|
|
|
FROM pg_range p1 JOIN pg_type t ON t.oid = p1.rngsubtype
|
|
|
|
WHERE (rngcollation = 0) != (typcollation = 0);
|
|
|
|
rngtypid | rngsubtype | rngcollation | typcollation
|
|
|
|
----------+------------+--------------+--------------
|
|
|
|
(0 rows)
|
|
|
|
|
|
|
|
-- opclass had better be a btree opclass accepting the subtype.
|
|
|
|
-- We must allow anyarray matches, cf opr_sanity's binary_coercible()
|
|
|
|
SELECT p1.rngtypid, p1.rngsubtype, o.opcmethod, o.opcname
|
|
|
|
FROM pg_range p1 JOIN pg_opclass o ON o.oid = p1.rngsubopc
|
|
|
|
WHERE o.opcmethod != 403 OR
|
|
|
|
((o.opcintype != p1.rngsubtype) AND NOT
|
|
|
|
(o.opcintype = 'pg_catalog.anyarray'::regtype AND
|
|
|
|
EXISTS(select 1 from pg_catalog.pg_type where
|
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 = p1.rngsubtype and typelem != 0 and
|
|
|
|
typsubscript = 'array_subscript_handler'::regproc)));
|
2011-11-17 00:21:34 +01:00
|
|
|
rngtypid | rngsubtype | opcmethod | opcname
|
|
|
|
----------+------------+-----------+---------
|
|
|
|
(0 rows)
|
|
|
|
|
|
|
|
-- canonical function, if any, had better match the range type
|
|
|
|
SELECT p1.rngtypid, p1.rngsubtype, p.proname
|
|
|
|
FROM pg_range p1 JOIN pg_proc p ON p.oid = p1.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 p1.rngtypid, p1.rngsubtype, p.proname
|
|
|
|
FROM pg_range p1 JOIN pg_proc p ON p.oid = p1.rngsubdiff
|
|
|
|
WHERE pronargs != 2
|
|
|
|
OR proargtypes[0] != rngsubtype OR proargtypes[1] != rngsubtype
|
|
|
|
OR prorettype != 'pg_catalog.float8'::regtype;
|
|
|
|
rngtypid | rngsubtype | proname
|
|
|
|
----------+------------+---------
|
|
|
|
(0 rows)
|
|
|
|
|
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with
set-theoretic operations defined over them.
Since v14, each range type automatically gets a corresponding multirange
datatype. There are both manual and automatic mechanisms for naming multirange
types. Once can specify multirange type name using multirange_type_name
attribute in CREATE TYPE. Otherwise, a multirange type name is generated
automatically. If the range type name contains "range" then we change that to
"multirange". Otherwise, we add "_multirange" to the end.
Implementation of multiranges comes with a space-efficient internal
representation format, which evades extra paddings and duplicated storage of
oids. Altogether this format allows fetching a particular range by its index
in O(n).
Statistic gathering and selectivity estimation are implemented for multiranges.
For this purpose, stored multirange is approximated as union range without gaps.
This field will likely need improvements in the future.
Catversion is bumped.
Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com
Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0
Author: Paul Jungwirth, revised by me
Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule
Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston
Reviewed-by: Zhihong Yu, Alexander Korotkov
2020-12-20 05:20:33 +01:00
|
|
|
-- every range should have a valid multirange
|
|
|
|
SELECT p1.rngtypid, p1.rngsubtype, p1.rngmultitypid
|
|
|
|
FROM pg_range p1
|
|
|
|
WHERE p1.rngmultitypid IS NULL OR p1.rngmultitypid = 0;
|
|
|
|
rngtypid | rngsubtype | rngmultitypid
|
|
|
|
----------+------------+---------------
|
|
|
|
(0 rows)
|
|
|
|
|