@@ -114,7 +114,11 @@ static void makeRangeConstructors(const char *name, Oid namespace,
114
114
Oid rangeOid , Oid subtype );
115
115
static void makeMultirangeConstructors (const char * name , Oid namespace ,
116
116
Oid multirangeOid , Oid rangeOid ,
117
- Oid rangeArrayOid , Oid * castFuncOid );
117
+ Oid rangeArrayOid ,
118
+ Oid * oneArgContructorOid );
119
+ static void makeMultirangeCasts (const char * name , Oid namespace ,
120
+ Oid multirangeOid , Oid rangeOid ,
121
+ Oid rangeArrayOid , Oid singleArgContructorOid );
118
122
static Oid findTypeInputFunction (List * procname , Oid typeOid );
119
123
static Oid findTypeOutputFunction (List * procname , Oid typeOid );
120
124
static Oid findTypeReceiveFunction (List * procname , Oid typeOid );
@@ -1365,7 +1369,7 @@ DefineRange(CreateRangeStmt *stmt)
1365
1369
ListCell * lc ;
1366
1370
ObjectAddress address ;
1367
1371
ObjectAddress mltrngaddress PG_USED_FOR_ASSERTS_ONLY ;
1368
- Oid castFuncOid ;
1372
+ Oid singleArgContructorOid ;
1369
1373
1370
1374
/* Convert list of names to a name and namespace */
1371
1375
typeNamespace = QualifiedNameGetCreationNamespace (stmt -> typeName ,
@@ -1717,10 +1721,12 @@ DefineRange(CreateRangeStmt *stmt)
1717
1721
makeRangeConstructors (typeName , typeNamespace , typoid , rangeSubtype );
1718
1722
makeMultirangeConstructors (multirangeTypeName , typeNamespace ,
1719
1723
multirangeOid , typoid , rangeArrayOid ,
1720
- & castFuncOid );
1724
+ & singleArgContructorOid );
1721
1725
1722
- /* Create cast from the range type to its multirange type */
1723
- CastCreate (typoid , multirangeOid , castFuncOid , 'e' , 'f' , DEPENDENCY_INTERNAL );
1726
+ /* Create casts for this multirange type */
1727
+ makeMultirangeCasts (multirangeTypeName , typeNamespace ,
1728
+ multirangeOid , typoid , rangeArrayOid ,
1729
+ singleArgContructorOid );
1724
1730
1725
1731
pfree (multirangeTypeName );
1726
1732
pfree (multirangeArrayName );
@@ -1808,13 +1814,13 @@ makeRangeConstructors(const char *name, Oid namespace,
1808
1814
* If we had an anyrangearray polymorphic type we could use it here,
1809
1815
* but since each type has its own constructor name there's no need.
1810
1816
*
1811
- * Sets castFuncOid to the oid of the new constructor that can be used
1817
+ * Sets oneArgContructorOid to the oid of the new constructor that can be used
1812
1818
* to cast from a range to a multirange.
1813
1819
*/
1814
1820
static void
1815
1821
makeMultirangeConstructors (const char * name , Oid namespace ,
1816
1822
Oid multirangeOid , Oid rangeOid , Oid rangeArrayOid ,
1817
- Oid * castFuncOid )
1823
+ Oid * oneArgContructorOid )
1818
1824
{
1819
1825
ObjectAddress myself ,
1820
1826
referenced ;
@@ -1904,7 +1910,7 @@ makeMultirangeConstructors(const char *name, Oid namespace,
1904
1910
/* ditto */
1905
1911
recordDependencyOn (& myself , & referenced , DEPENDENCY_INTERNAL );
1906
1912
pfree (argtypes );
1907
- * castFuncOid = myself .objectId ;
1913
+ * oneArgContructorOid = myself .objectId ;
1908
1914
1909
1915
/* n-arg constructor - vararg */
1910
1916
argtypes = buildoidvector (& rangeArrayOid , 1 );
@@ -1949,6 +1955,76 @@ makeMultirangeConstructors(const char *name, Oid namespace,
1949
1955
pfree (parameterModes );
1950
1956
}
1951
1957
1958
+ /*
1959
+ * Create casts for the multirange type. The first cast makes multirange from
1960
+ * range, and it's based on the single-argument constructor. The second cast
1961
+ * makes an array of ranges from multirange.
1962
+ */
1963
+ static void
1964
+ makeMultirangeCasts (const char * name , Oid namespace ,
1965
+ Oid multirangeOid , Oid rangeOid , Oid rangeArrayOid ,
1966
+ Oid singleArgContructorOid )
1967
+ {
1968
+ ObjectAddress myself ,
1969
+ referenced ;
1970
+ oidvector * argtypes ;
1971
+
1972
+ /*
1973
+ * Create cast from range to multirange using the existing single-argument
1974
+ * constructor procedure.
1975
+ */
1976
+ CastCreate (rangeOid , multirangeOid , singleArgContructorOid , 'e' , 'f' ,
1977
+ DEPENDENCY_INTERNAL );
1978
+
1979
+ referenced .classId = TypeRelationId ;
1980
+ referenced .objectId = multirangeOid ;
1981
+ referenced .objectSubId = 0 ;
1982
+
1983
+ /* multirange_to_array() function */
1984
+ argtypes = buildoidvector (& multirangeOid , 1 );
1985
+ myself = ProcedureCreate ("multirange_to_array" , /* name */
1986
+ namespace ,
1987
+ false, /* replace */
1988
+ false, /* returns set */
1989
+ rangeArrayOid , /* return type */
1990
+ BOOTSTRAP_SUPERUSERID , /* proowner */
1991
+ INTERNALlanguageId , /* language */
1992
+ F_FMGR_INTERNAL_VALIDATOR ,
1993
+ "multirange_to_array" , /* prosrc */
1994
+ NULL , /* probin */
1995
+ NULL , /* prosqlbody */
1996
+ PROKIND_FUNCTION ,
1997
+ false, /* security_definer */
1998
+ false, /* leakproof */
1999
+ true, /* isStrict */
2000
+ PROVOLATILE_IMMUTABLE , /* volatility */
2001
+ PROPARALLEL_SAFE , /* parallel safety */
2002
+ argtypes , /* parameterTypes */
2003
+ PointerGetDatum (NULL ), /* allParameterTypes */
2004
+ PointerGetDatum (NULL ), /* parameterModes */
2005
+ PointerGetDatum (NULL ), /* parameterNames */
2006
+ NIL , /* parameterDefaults */
2007
+ PointerGetDatum (NULL ), /* trftypes */
2008
+ PointerGetDatum (NULL ), /* proconfig */
2009
+ InvalidOid , /* prosupport */
2010
+ 1.0 , /* procost */
2011
+ 0.0 ); /* prorows */
2012
+
2013
+ /*
2014
+ * Make the multirange_to_array() function internally-dependent on the
2015
+ * multirange type so that they go away silently when the type is dropped.
2016
+ */
2017
+ recordDependencyOn (& myself , & referenced , DEPENDENCY_INTERNAL );
2018
+ pfree (argtypes );
2019
+
2020
+ /*
2021
+ * Create cast from multirange to the array of ranges using
2022
+ * multirange_to_array() function.
2023
+ */
2024
+ CastCreate (multirangeOid , rangeArrayOid , myself .objectId , 'e' , 'f' ,
2025
+ DEPENDENCY_INTERNAL );
2026
+ }
2027
+
1952
2028
/*
1953
2029
* Find suitable I/O and other support functions for a type.
1954
2030
*
0 commit comments