diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2020-03-19 11:43:11 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2020-03-19 11:43:11 -0400 |
commit | 24e2885ee304cb6a94fdfc25a1a108344ed9f4f7 (patch) | |
tree | 040c3eead18de05e313c808e07aee262ef2de336 /src/include | |
parent | fab13dc50ba5e7a12b474a7366024681bc169ac8 (diff) |
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
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
-rw-r--r-- | src/include/catalog/pg_proc.dat | 45 | ||||
-rw-r--r-- | src/include/catalog/pg_type.dat | 30 | ||||
-rw-r--r-- | src/include/catalog/pg_type.h | 11 |
4 files changed, 81 insertions, 7 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 3fee9342cc1..50069bea0e1 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202003181 +#define CATALOG_VERSION_NO 202003191 #endif diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index a64378b0027..87d25d4a4bd 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -6673,8 +6673,9 @@ proname => 'regcollationout', provolatile => 's', prorettype => 'cstring', proargtypes => 'regcollation', prosrc => 'regcollationout' }, { oid => '4195', descr => 'convert classname to regcollation', - proname => 'to_regcollation', provolatile => 's', prorettype => 'regcollation', - proargtypes => 'text', prosrc => 'to_regcollation' }, + proname => 'to_regcollation', provolatile => 's', + prorettype => 'regcollation', proargtypes => 'text', + prosrc => 'to_regcollation' }, { oid => '2220', descr => 'I/O', proname => 'regtypein', provolatile => 's', prorettype => 'regtype', proargtypes => 'cstring', prosrc => 'regtypein' }, @@ -7115,6 +7116,42 @@ { oid => '268', descr => 'I/O', proname => 'table_am_handler_out', prorettype => 'cstring', proargtypes => 'table_am_handler', prosrc => 'table_am_handler_out' }, +{ oid => '9559', descr => 'I/O', + proname => 'anycompatible_in', prorettype => 'anycompatible', + proargtypes => 'cstring', prosrc => 'anycompatible_in' }, +{ oid => '9560', descr => 'I/O', + proname => 'anycompatible_out', prorettype => 'cstring', + proargtypes => 'anycompatible', prosrc => 'anycompatible_out' }, +{ oid => '9561', descr => 'I/O', + proname => 'anycompatiblearray_in', prorettype => 'anycompatiblearray', + proargtypes => 'cstring', prosrc => 'anycompatiblearray_in' }, +{ oid => '9562', descr => 'I/O', + proname => 'anycompatiblearray_out', provolatile => 's', + prorettype => 'cstring', proargtypes => 'anycompatiblearray', + prosrc => 'anycompatiblearray_out' }, +{ oid => '9563', descr => 'I/O', + proname => 'anycompatiblearray_recv', provolatile => 's', + prorettype => 'anycompatiblearray', proargtypes => 'internal', + prosrc => 'anycompatiblearray_recv' }, +{ oid => '9564', descr => 'I/O', + proname => 'anycompatiblearray_send', provolatile => 's', + prorettype => 'bytea', proargtypes => 'anycompatiblearray', + prosrc => 'anycompatiblearray_send' }, +{ oid => '9565', descr => 'I/O', + proname => 'anycompatiblenonarray_in', prorettype => 'anycompatiblenonarray', + proargtypes => 'cstring', prosrc => 'anycompatiblenonarray_in' }, +{ oid => '9566', descr => 'I/O', + proname => 'anycompatiblenonarray_out', prorettype => 'cstring', + proargtypes => 'anycompatiblenonarray', + prosrc => 'anycompatiblenonarray_out' }, +{ oid => '9567', descr => 'I/O', + proname => 'anycompatiblerange_in', provolatile => 's', + prorettype => 'anycompatiblerange', proargtypes => 'cstring oid int4', + prosrc => 'anycompatiblerange_in' }, +{ oid => '9568', descr => 'I/O', + proname => 'anycompatiblerange_out', provolatile => 's', + prorettype => 'cstring', proargtypes => 'anycompatiblerange', + prosrc => 'anycompatiblerange_out' }, # tablesample method handlers { oid => '3313', descr => 'BERNOULLI tablesample method handler', @@ -7459,8 +7496,8 @@ proname => 'regcollationrecv', prorettype => 'regcollation', proargtypes => 'internal', prosrc => 'regcollationrecv' }, { oid => '4197', descr => 'I/O', - proname => 'regcollationsend', prorettype => 'bytea', proargtypes => 'regcollation', - prosrc => 'regcollationsend' }, + proname => 'regcollationsend', prorettype => 'bytea', + proargtypes => 'regcollation', prosrc => 'regcollationsend' }, { oid => '2454', descr => 'I/O', proname => 'regtyperecv', prorettype => 'regtype', proargtypes => 'internal', prosrc => 'regtyperecv' }, diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat index bb21cf166db..2e6110e3f2c 100644 --- a/src/include/catalog/pg_type.dat +++ b/src/include/catalog/pg_type.dat @@ -382,7 +382,8 @@ { oid => '4191', array_type_oid => '4192', descr => 'registered collation', typname => 'regcollation', typlen => '4', typbyval => 't', typcategory => 'N', typinput => 'regcollationin', typoutput => 'regcollationout', - typreceive => 'regcollationrecv', typsend => 'regcollationsend', typalign => 'i' }, + typreceive => 'regcollationrecv', typsend => 'regcollationsend', + typalign => 'i' }, { oid => '2206', array_type_oid => '2211', descr => 'registered type', typname => 'regtype', typlen => '4', typbyval => 't', typcategory => 'N', typinput => 'regtypein', typoutput => 'regtypeout', @@ -590,9 +591,34 @@ typoutput => 'table_am_handler_out', typreceive => '-', typsend => '-', typalign => 'i' }, { oid => '3831', - descr => 'pseudo-type representing a polymorphic base type that is a range', + descr => 'pseudo-type representing a range over a polymorphic base type', typname => 'anyrange', typlen => '-1', typbyval => 'f', typtype => 'p', typcategory => 'P', typinput => 'anyrange_in', typoutput => 'anyrange_out', typreceive => '-', typsend => '-', typalign => 'd', typstorage => 'x' }, +{ oid => '9550', + descr => 'pseudo-type representing a polymorphic common type', + typname => 'anycompatible', typlen => '4', typbyval => 't', typtype => 'p', + typcategory => 'P', typinput => 'anycompatible_in', + typoutput => 'anycompatible_out', typreceive => '-', typsend => '-', + typalign => 'i' }, +{ oid => '9551', + descr => 'pseudo-type representing an array of polymorphic common type elements', + typname => 'anycompatiblearray', typlen => '-1', typbyval => 'f', + typtype => 'p', typcategory => 'P', typinput => 'anycompatiblearray_in', + typoutput => 'anycompatiblearray_out', + typreceive => 'anycompatiblearray_recv', typsend => 'anycompatiblearray_send', + typalign => 'd', typstorage => 'x' }, +{ oid => '9552', + descr => 'pseudo-type representing a polymorphic common type that is not an array', + typname => 'anycompatiblenonarray', typlen => '4', typbyval => 't', + typtype => 'p', typcategory => 'P', typinput => 'anycompatiblenonarray_in', + typoutput => 'anycompatiblenonarray_out', typreceive => '-', typsend => '-', + typalign => 'i' }, +{ oid => '9553', + descr => 'pseudo-type representing a range over a polymorphic common type', + typname => 'anycompatiblerange', typlen => '-1', typbyval => 'f', + typtype => 'p', typcategory => 'P', typinput => 'anycompatiblerange_in', + typoutput => 'anycompatiblerange_out', typreceive => '-', typsend => '-', + typalign => 'd', typstorage => 'x' }, ] diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index 97890946c5d..7b375626484 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -295,12 +295,23 @@ typedef FormData_pg_type *Form_pg_type; /* Is a type OID a polymorphic pseudotype? (Beware of multiple evaluation) */ #define IsPolymorphicType(typid) \ + (IsPolymorphicTypeFamily1(typid) || \ + IsPolymorphicTypeFamily2(typid)) + +/* Code not part of polymorphic type resolution should not use these macros: */ +#define IsPolymorphicTypeFamily1(typid) \ ((typid) == ANYELEMENTOID || \ (typid) == ANYARRAYOID || \ (typid) == ANYNONARRAYOID || \ (typid) == ANYENUMOID || \ (typid) == ANYRANGEOID) +#define IsPolymorphicTypeFamily2(typid) \ + ((typid) == ANYCOMPATIBLEOID || \ + (typid) == ANYCOMPATIBLEARRAYOID || \ + (typid) == ANYCOMPATIBLENONARRAYOID || \ + (typid) == ANYCOMPATIBLERANGEOID) + #endif /* EXPOSE_TO_CLIENT_CODE */ |