From 82a087573dd60765321abb7904de271404e59e6f Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 19 Jan 2026 13:54:41 +0100 Subject: [PATCH v2] Record range constructor functions in pg_range When a range type is created, several construction functions are also created, two for the range type and three for the multirange type. These have an internal dependency, so they "belong" to the range type. But there was no way to identify those functions when given a range type. An upcoming patch needs access to the two- or possibly the three-argument range constructor function for a given range type. The only way to do that would be with fragile workarounds like matching names and argument types. The correct way to do that kind of thing is to record to the links in the system catalogs. This is what this patch does, it records the OIDs of these five constructor functions in the pg_range catalog. (Currently, there is no code that makes use of this.) Reviewed-by: Paul A Jungwirth Discussion: https://www.postgresql.org/message-id/7d63ddfa-c735-4dfe-8c7a-4f1e2a621058%40eisentraut.org TODO: catversion --- doc/src/sgml/catalogs.sgml | 54 +++++++++++++++++++++ src/backend/catalog/pg_range.c | 9 +++- src/backend/commands/typecmds.c | 48 +++++++++++++----- src/include/catalog/pg_range.dat | 12 +++++ src/include/catalog/pg_range.h | 13 ++++- src/test/regress/expected/oidjoins.out | 5 ++ src/test/regress/expected/type_sanity.out | 59 ++++++++++++++++++++++- src/test/regress/sql/type_sanity.sql | 47 +++++++++++++++++- 8 files changed, 230 insertions(+), 17 deletions(-) diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 2fc63442980..332193565e2 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -6676,6 +6676,60 @@ <structname>pg_range</structname> Columns + + + rngconstruct2 regproc + (references pg_proc.oid) + + + OID of the 2-argument range constructor function (lower and upper) + + + + + + rngconstruct3 regproc + (references pg_proc.oid) + + + OID of the 3-argument range constructor function (lower, upper, and + flags) + + + + + + rngmltconstruct0 regproc + (references pg_proc.oid) + + + OID of the 0-argument multirange constructor function (constructs empty + range) + + + + + + rngmltconstruct1 regproc + (references pg_proc.oid) + + + OID of the 1-argument multirange constructor function (constructs + multirange from single range, also used as cast function) + + + + + + rngmltconstruct2 regproc + (references pg_proc.oid) + + + OID of the 2-argument multirange constructor function (constructs + multirange from array of ranges) + + + rngcanonical regproc diff --git a/src/backend/catalog/pg_range.c b/src/backend/catalog/pg_range.c index cd21c84c8fd..cb8c79d0e83 100644 --- a/src/backend/catalog/pg_range.c +++ b/src/backend/catalog/pg_range.c @@ -35,7 +35,9 @@ void RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, Oid rangeSubOpclass, RegProcedure rangeCanonical, - RegProcedure rangeSubDiff, Oid multirangeTypeOid) + RegProcedure rangeSubDiff, Oid multirangeTypeOid, + RegProcedure rangeConstruct2, RegProcedure rangeConstruct3, + RegProcedure mltrngConstruct0, RegProcedure mltrngConstruct1, RegProcedure mltrngConstruct2) { Relation pg_range; Datum values[Natts_pg_range]; @@ -57,6 +59,11 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, values[Anum_pg_range_rngcanonical - 1] = ObjectIdGetDatum(rangeCanonical); values[Anum_pg_range_rngsubdiff - 1] = ObjectIdGetDatum(rangeSubDiff); values[Anum_pg_range_rngmultitypid - 1] = ObjectIdGetDatum(multirangeTypeOid); + values[Anum_pg_range_rngconstruct2 - 1] = ObjectIdGetDatum(rangeConstruct2); + values[Anum_pg_range_rngconstruct3 - 1] = ObjectIdGetDatum(rangeConstruct3); + values[Anum_pg_range_rngmltconstruct0 - 1] = ObjectIdGetDatum(mltrngConstruct0); + values[Anum_pg_range_rngmltconstruct1 - 1] = ObjectIdGetDatum(mltrngConstruct1); + values[Anum_pg_range_rngmltconstruct2 - 1] = ObjectIdGetDatum(mltrngConstruct2); tup = heap_form_tuple(RelationGetDescr(pg_range), values, nulls); diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index e5fa0578889..288edb25f2f 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -111,10 +111,12 @@ Oid binary_upgrade_next_mrng_pg_type_oid = InvalidOid; Oid binary_upgrade_next_mrng_array_pg_type_oid = InvalidOid; static void makeRangeConstructors(const char *name, Oid namespace, - Oid rangeOid, Oid subtype); + Oid rangeOid, Oid subtype, + Oid *rangeConstruct2_p, Oid *rangeConstruct3_p); static void makeMultirangeConstructors(const char *name, Oid namespace, Oid multirangeOid, Oid rangeOid, - Oid rangeArrayOid, Oid *castFuncOid); + Oid rangeArrayOid, + Oid *mltrngConstruct0_p, Oid *mltrngConstruct1_p, Oid *mltrngConstruct2_p); static Oid findTypeInputFunction(List *procname, Oid typeOid); static Oid findTypeOutputFunction(List *procname, Oid typeOid); static Oid findTypeReceiveFunction(List *procname, Oid typeOid); @@ -1406,6 +1408,11 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt) ListCell *lc; ObjectAddress address; ObjectAddress mltrngaddress PG_USED_FOR_ASSERTS_ONLY; + Oid rangeConstruct2Oid = InvalidOid; + Oid rangeConstruct3Oid = InvalidOid; + Oid mltrngConstruct0Oid = InvalidOid; + Oid mltrngConstruct1Oid = InvalidOid; + Oid mltrngConstruct2Oid = InvalidOid; Oid castFuncOid; /* Convert list of names to a name and namespace */ @@ -1661,10 +1668,6 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt) InvalidOid); /* type's collation (ranges never have one) */ Assert(multirangeOid == mltrngaddress.objectId); - /* Create the entry in pg_range */ - RangeCreate(typoid, rangeSubtype, rangeCollation, rangeSubOpclass, - rangeCanonical, rangeSubtypeDiff, multirangeOid); - /* * Create the array type that goes with it. */ @@ -1746,10 +1749,18 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt) CommandCounterIncrement(); /* And create the constructor functions for this range type */ - makeRangeConstructors(typeName, typeNamespace, typoid, rangeSubtype); + makeRangeConstructors(typeName, typeNamespace, typoid, rangeSubtype, + &rangeConstruct2Oid, &rangeConstruct3Oid); makeMultirangeConstructors(multirangeTypeName, typeNamespace, multirangeOid, typoid, rangeArrayOid, - &castFuncOid); + &mltrngConstruct0Oid, &mltrngConstruct1Oid, &mltrngConstruct2Oid); + castFuncOid = mltrngConstruct1Oid; + + /* Create the entry in pg_range */ + RangeCreate(typoid, rangeSubtype, rangeCollation, rangeSubOpclass, + rangeCanonical, rangeSubtypeDiff, multirangeOid, + rangeConstruct2Oid, rangeConstruct3Oid, + mltrngConstruct0Oid, mltrngConstruct1Oid, mltrngConstruct2Oid); /* Create cast from the range type to its multirange type */ CastCreate(typoid, multirangeOid, castFuncOid, InvalidOid, InvalidOid, @@ -1769,10 +1780,14 @@ DefineRange(ParseState *pstate, CreateRangeStmt *stmt) * * We actually define 2 functions, with 2 through 3 arguments. This is just * to offer more convenience for the user. + * + * The OIDs of the created functions are returned through the pointer + * arguments. */ static void makeRangeConstructors(const char *name, Oid namespace, - Oid rangeOid, Oid subtype) + Oid rangeOid, Oid subtype, + Oid *rangeConstruct2_p, Oid *rangeConstruct3_p) { static const char *const prosrc[2] = {"range_constructor2", "range_constructor3"}; @@ -1833,6 +1848,11 @@ makeRangeConstructors(const char *name, Oid namespace, * pg_dump depends on this choice to avoid dumping the constructors. */ recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL); + + if (pronargs[i] == 2) + *rangeConstruct2_p = myself.objectId; + else if (pronargs[i] == 3) + *rangeConstruct3_p = myself.objectId; } } @@ -1842,13 +1862,13 @@ makeRangeConstructors(const char *name, Oid namespace, * If we had an anyrangearray polymorphic type we could use it here, * but since each type has its own constructor name there's no need. * - * Sets castFuncOid to the oid of the new constructor that can be used - * to cast from a range to a multirange. + * The OIDs of the created functions are returned through the pointer + * arguments. */ static void makeMultirangeConstructors(const char *name, Oid namespace, Oid multirangeOid, Oid rangeOid, Oid rangeArrayOid, - Oid *castFuncOid) + Oid *mltrngConstruct0_p, Oid *mltrngConstruct1_p, Oid *mltrngConstruct2_p) { ObjectAddress myself, referenced; @@ -1899,6 +1919,7 @@ makeMultirangeConstructors(const char *name, Oid namespace, * depends on this choice to avoid dumping the constructors. */ recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL); + *mltrngConstruct0_p = myself.objectId; pfree(argtypes); /* @@ -1939,8 +1960,8 @@ makeMultirangeConstructors(const char *name, Oid namespace, 0.0); /* prorows */ /* ditto */ recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL); + *mltrngConstruct1_p = myself.objectId; pfree(argtypes); - *castFuncOid = myself.objectId; /* n-arg constructor - vararg */ argtypes = buildoidvector(&rangeArrayOid, 1); @@ -1978,6 +1999,7 @@ makeMultirangeConstructors(const char *name, Oid namespace, 0.0); /* prorows */ /* ditto */ recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL); + *mltrngConstruct2_p = myself.objectId; pfree(argtypes); pfree(allParameterTypes); pfree(parameterModes); diff --git a/src/include/catalog/pg_range.dat b/src/include/catalog/pg_range.dat index 830971c4944..fa5e6ff0c3e 100644 --- a/src/include/catalog/pg_range.dat +++ b/src/include/catalog/pg_range.dat @@ -14,21 +14,33 @@ { rngtypid => 'int4range', rngsubtype => 'int4', rngmultitypid => 'int4multirange', rngsubopc => 'btree/int4_ops', + rngconstruct2 => 'int4range(int4,int4)', rngconstruct3 => 'int4range(int4,int4,text)', + rngmltconstruct0 => 'int4multirange()', rngmltconstruct1 => 'int4multirange(int4range)', rngmltconstruct2 => 'int4multirange(_int4range)', rngcanonical => 'int4range_canonical', rngsubdiff => 'int4range_subdiff' }, { rngtypid => 'numrange', rngsubtype => 'numeric', rngmultitypid => 'nummultirange', rngsubopc => 'btree/numeric_ops', + rngconstruct2 => 'numrange(numeric,numeric)', rngconstruct3 => 'numrange(numeric,numeric,text)', + rngmltconstruct0 => 'nummultirange()', rngmltconstruct1 => 'nummultirange(numrange)', rngmltconstruct2 => 'nummultirange(_numrange)', rngcanonical => '-', rngsubdiff => 'numrange_subdiff' }, { rngtypid => 'tsrange', rngsubtype => 'timestamp', rngmultitypid => 'tsmultirange', rngsubopc => 'btree/timestamp_ops', + rngconstruct2 => 'tsrange(timestamp,timestamp)', rngconstruct3 => 'tsrange(timestamp,timestamp,text)', + rngmltconstruct0 => 'tsmultirange()', rngmltconstruct1 => 'tsmultirange(tsrange)', rngmltconstruct2 => 'tsmultirange(_tsrange)', rngcanonical => '-', rngsubdiff => 'tsrange_subdiff' }, { rngtypid => 'tstzrange', rngsubtype => 'timestamptz', rngmultitypid => 'tstzmultirange', rngsubopc => 'btree/timestamptz_ops', + rngconstruct2 => 'tstzrange(timestamptz,timestamptz)', rngconstruct3 => 'tstzrange(timestamptz,timestamptz,text)', + rngmltconstruct0 => 'tstzmultirange()', rngmltconstruct1 => 'tstzmultirange(tstzrange)', rngmltconstruct2 => 'tstzmultirange(_tstzrange)', rngcanonical => '-', rngsubdiff => 'tstzrange_subdiff' }, { rngtypid => 'daterange', rngsubtype => 'date', rngmultitypid => 'datemultirange', rngsubopc => 'btree/date_ops', + rngconstruct2 => 'daterange(date,date)', rngconstruct3 => 'daterange(date,date,text)', + rngmltconstruct0 => 'datemultirange()', rngmltconstruct1 => 'datemultirange(daterange)', rngmltconstruct2 => 'datemultirange(_daterange)', rngcanonical => 'daterange_canonical', rngsubdiff => 'daterange_subdiff' }, { rngtypid => 'int8range', rngsubtype => 'int8', rngmultitypid => 'int8multirange', rngsubopc => 'btree/int8_ops', + rngconstruct2 => 'int8range(int8,int8)', rngconstruct3 => 'int8range(int8,int8,text)', + rngmltconstruct0 => 'int8multirange()', rngmltconstruct1 => 'int8multirange(int8range)', rngmltconstruct2 => 'int8multirange(_int8range)', rngcanonical => 'int8range_canonical', rngsubdiff => 'int8range_subdiff' }, ] diff --git a/src/include/catalog/pg_range.h b/src/include/catalog/pg_range.h index 5b4f4615905..32ee8cf43a0 100644 --- a/src/include/catalog/pg_range.h +++ b/src/include/catalog/pg_range.h @@ -43,6 +43,15 @@ CATALOG(pg_range,3541,RangeRelationId) /* subtype's btree opclass */ Oid rngsubopc BKI_LOOKUP(pg_opclass); + /* range constructor functions */ + regproc rngconstruct2 BKI_LOOKUP(pg_proc); + regproc rngconstruct3 BKI_LOOKUP(pg_proc); + + /* multirange constructor functions */ + regproc rngmltconstruct0 BKI_LOOKUP(pg_proc); + regproc rngmltconstruct1 BKI_LOOKUP(pg_proc); + regproc rngmltconstruct2 BKI_LOOKUP(pg_proc); + /* canonicalize range, or 0 */ regproc rngcanonical BKI_LOOKUP_OPT(pg_proc); @@ -69,7 +78,9 @@ MAKE_SYSCACHE(RANGEMULTIRANGE, pg_range_rngmultitypid_index, 4); extern void RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, Oid rangeSubOpclass, RegProcedure rangeCanonical, - RegProcedure rangeSubDiff, Oid multirangeTypeOid); + RegProcedure rangeSubDiff, Oid multirangeTypeOid, + RegProcedure rangeConstruct2, RegProcedure rangeConstruct3, + RegProcedure mltrngConstruct0, RegProcedure mltrngConstruct1, RegProcedure mltrngConstruct2); extern void RangeDelete(Oid rangeTypeOid); #endif /* PG_RANGE_H */ diff --git a/src/test/regress/expected/oidjoins.out b/src/test/regress/expected/oidjoins.out index 215eb899be3..25aaae8d05a 100644 --- a/src/test/regress/expected/oidjoins.out +++ b/src/test/regress/expected/oidjoins.out @@ -249,6 +249,11 @@ NOTICE: checking pg_range {rngsubtype} => pg_type {oid} NOTICE: checking pg_range {rngmultitypid} => pg_type {oid} NOTICE: checking pg_range {rngcollation} => pg_collation {oid} NOTICE: checking pg_range {rngsubopc} => pg_opclass {oid} +NOTICE: checking pg_range {rngconstruct2} => pg_proc {oid} +NOTICE: checking pg_range {rngconstruct3} => pg_proc {oid} +NOTICE: checking pg_range {rngmltconstruct0} => pg_proc {oid} +NOTICE: checking pg_range {rngmltconstruct1} => pg_proc {oid} +NOTICE: checking pg_range {rngmltconstruct2} => pg_proc {oid} NOTICE: checking pg_range {rngcanonical} => pg_proc {oid} NOTICE: checking pg_range {rngsubdiff} => pg_proc {oid} NOTICE: checking pg_transform {trftype} => pg_type {oid} diff --git a/src/test/regress/expected/type_sanity.out b/src/test/regress/expected/type_sanity.out index 9ddcacec6bf..1d21d3eb446 100644 --- a/src/test/regress/expected/type_sanity.out +++ b/src/test/regress/expected/type_sanity.out @@ -610,7 +610,9 @@ WHERE (is_catalog_text_unique_index_oid(indexrelid) <> -- Look for illegal values in pg_range fields. SELECT r.rngtypid, r.rngsubtype FROM pg_range as r -WHERE r.rngtypid = 0 OR r.rngsubtype = 0 OR r.rngsubopc = 0; +WHERE r.rngtypid = 0 OR r.rngsubtype = 0 OR r.rngsubopc = 0 + OR r.rngconstruct2 = 0 OR r.rngconstruct3 = 0 + OR r.rngmltconstruct0 = 0 OR r.rngmltconstruct1 = 0 OR r.rngmltconstruct2 = 0; rngtypid | rngsubtype ----------+------------ (0 rows) @@ -663,6 +665,61 @@ WHERE r.rngmultitypid IS NULL OR r.rngmultitypid = 0; ----------+------------+--------------- (0 rows) +-- check constructor function arguments and return types +-- +-- proname and prosrc are not required to have these particular +-- values, but this matches what DefineRange() produces and serves to +-- sanity-check the catalog entries for built-in types. +SELECT r.rngtypid, r.rngsubtype, p.proname +FROM pg_range r JOIN pg_proc p ON p.oid = r.rngconstruct2 JOIN pg_type t ON r.rngtypid = t.oid +WHERE p.pronargs != 2 + OR p.proargtypes[0] != r.rngsubtype OR p.proargtypes[1] != r.rngsubtype + OR p.prorettype != r.rngtypid + OR p.proname != t.typname OR p.prosrc != 'range_constructor2'; + rngtypid | rngsubtype | proname +----------+------------+--------- +(0 rows) + +SELECT r.rngtypid, r.rngsubtype, p.proname +FROM pg_range r JOIN pg_proc p ON p.oid = r.rngconstruct3 JOIN pg_type t ON r.rngtypid = t.oid +WHERE p.pronargs != 3 + OR p.proargtypes[0] != r.rngsubtype OR p.proargtypes[1] != r.rngsubtype OR p.proargtypes[2] != 'pg_catalog.text'::regtype + OR p.prorettype != r.rngtypid + OR p.proname != t.typname OR p.prosrc != 'range_constructor3'; + rngtypid | rngsubtype | proname +----------+------------+--------- +(0 rows) + +SELECT r.rngtypid, r.rngsubtype, p.proname +FROM pg_range r JOIN pg_proc p ON p.oid = r.rngmltconstruct0 JOIN pg_type t ON r.rngmultitypid = t.oid +WHERE p.pronargs != 0 + OR p.prorettype != r.rngmultitypid + OR p.proname != t.typname OR p.prosrc != 'multirange_constructor0'; + rngtypid | rngsubtype | proname +----------+------------+--------- +(0 rows) + +SELECT r.rngtypid, r.rngsubtype, p.proname +FROM pg_range r JOIN pg_proc p ON p.oid = r.rngmltconstruct1 JOIN pg_type t ON r.rngmultitypid = t.oid +WHERE p.pronargs != 1 + OR p.proargtypes[0] != r.rngtypid + OR p.prorettype != r.rngmultitypid + OR p.proname != t.typname OR p.prosrc != 'multirange_constructor1'; + rngtypid | rngsubtype | proname +----------+------------+--------- +(0 rows) + +SELECT r.rngtypid, r.rngsubtype, p.proname +FROM pg_range r JOIN pg_proc p ON p.oid = r.rngmltconstruct2 JOIN pg_type t ON r.rngmultitypid = t.oid JOIN pg_type t2 ON r.rngtypid = t2.oid +WHERE p.pronargs != 1 + OR p.proargtypes[0] != t2.typarray + OR p.prorettype != r.rngmultitypid + OR p.proname != t.typname OR p.prosrc != 'multirange_constructor2'; + rngtypid | rngsubtype | proname +----------+------------+--------- +(0 rows) + +-- ****************************************** -- Create a table that holds all the known in-core data types and leave it -- around so as pg_upgrade is able to test their binary compatibility. CREATE TABLE tab_core_types AS SELECT diff --git a/src/test/regress/sql/type_sanity.sql b/src/test/regress/sql/type_sanity.sql index c2496823d90..95d5b6e0915 100644 --- a/src/test/regress/sql/type_sanity.sql +++ b/src/test/regress/sql/type_sanity.sql @@ -451,7 +451,9 @@ CREATE FUNCTION is_catalog_text_unique_index_oid(oid) RETURNS bool SELECT r.rngtypid, r.rngsubtype FROM pg_range as r -WHERE r.rngtypid = 0 OR r.rngsubtype = 0 OR r.rngsubopc = 0; +WHERE r.rngtypid = 0 OR r.rngsubtype = 0 OR r.rngsubopc = 0 + OR r.rngconstruct2 = 0 OR r.rngconstruct3 = 0 + OR r.rngmltconstruct0 = 0 OR r.rngmltconstruct1 = 0 OR r.rngmltconstruct2 = 0; -- rngcollation should be specified iff subtype is collatable @@ -491,6 +493,49 @@ CREATE FUNCTION is_catalog_text_unique_index_oid(oid) RETURNS bool FROM pg_range r WHERE r.rngmultitypid IS NULL OR r.rngmultitypid = 0; +-- check constructor function arguments and return types +-- +-- proname and prosrc are not required to have these particular +-- values, but this matches what DefineRange() produces and serves to +-- sanity-check the catalog entries for built-in types. + +SELECT r.rngtypid, r.rngsubtype, p.proname +FROM pg_range r JOIN pg_proc p ON p.oid = r.rngconstruct2 JOIN pg_type t ON r.rngtypid = t.oid +WHERE p.pronargs != 2 + OR p.proargtypes[0] != r.rngsubtype OR p.proargtypes[1] != r.rngsubtype + OR p.prorettype != r.rngtypid + OR p.proname != t.typname OR p.prosrc != 'range_constructor2'; + +SELECT r.rngtypid, r.rngsubtype, p.proname +FROM pg_range r JOIN pg_proc p ON p.oid = r.rngconstruct3 JOIN pg_type t ON r.rngtypid = t.oid +WHERE p.pronargs != 3 + OR p.proargtypes[0] != r.rngsubtype OR p.proargtypes[1] != r.rngsubtype OR p.proargtypes[2] != 'pg_catalog.text'::regtype + OR p.prorettype != r.rngtypid + OR p.proname != t.typname OR p.prosrc != 'range_constructor3'; + +SELECT r.rngtypid, r.rngsubtype, p.proname +FROM pg_range r JOIN pg_proc p ON p.oid = r.rngmltconstruct0 JOIN pg_type t ON r.rngmultitypid = t.oid +WHERE p.pronargs != 0 + OR p.prorettype != r.rngmultitypid + OR p.proname != t.typname OR p.prosrc != 'multirange_constructor0'; + +SELECT r.rngtypid, r.rngsubtype, p.proname +FROM pg_range r JOIN pg_proc p ON p.oid = r.rngmltconstruct1 JOIN pg_type t ON r.rngmultitypid = t.oid +WHERE p.pronargs != 1 + OR p.proargtypes[0] != r.rngtypid + OR p.prorettype != r.rngmultitypid + OR p.proname != t.typname OR p.prosrc != 'multirange_constructor1'; + +SELECT r.rngtypid, r.rngsubtype, p.proname +FROM pg_range r JOIN pg_proc p ON p.oid = r.rngmltconstruct2 JOIN pg_type t ON r.rngmultitypid = t.oid JOIN pg_type t2 ON r.rngtypid = t2.oid +WHERE p.pronargs != 1 + OR p.proargtypes[0] != t2.typarray + OR p.prorettype != r.rngmultitypid + OR p.proname != t.typname OR p.prosrc != 'multirange_constructor2'; + + +-- ****************************************** + -- Create a table that holds all the known in-core data types and leave it -- around so as pg_upgrade is able to test their binary compatibility. CREATE TABLE tab_core_types AS SELECT base-commit: 34740b90bc123d645a3a71231b765b778bdcf049 -- 2.52.0