@@ -114,7 +114,11 @@ static void makeRangeConstructors(const char *name, Oid namespace,
114114 Oid rangeOid , Oid subtype );
115115static void makeMultirangeConstructors (const char * name , Oid namespace ,
116116 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 );
118122static Oid findTypeInputFunction (List * procname , Oid typeOid );
119123static Oid findTypeOutputFunction (List * procname , Oid typeOid );
120124static Oid findTypeReceiveFunction (List * procname , Oid typeOid );
@@ -1365,7 +1369,7 @@ DefineRange(CreateRangeStmt *stmt)
13651369 ListCell * lc ;
13661370 ObjectAddress address ;
13671371 ObjectAddress mltrngaddress PG_USED_FOR_ASSERTS_ONLY ;
1368- Oid castFuncOid ;
1372+ Oid singleArgContructorOid ;
13691373
13701374 /* Convert list of names to a name and namespace */
13711375 typeNamespace = QualifiedNameGetCreationNamespace (stmt -> typeName ,
@@ -1717,10 +1721,12 @@ DefineRange(CreateRangeStmt *stmt)
17171721 makeRangeConstructors (typeName , typeNamespace , typoid , rangeSubtype );
17181722 makeMultirangeConstructors (multirangeTypeName , typeNamespace ,
17191723 multirangeOid , typoid , rangeArrayOid ,
1720- & castFuncOid );
1724+ & singleArgContructorOid );
17211725
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 );
17241730
17251731 pfree (multirangeTypeName );
17261732 pfree (multirangeArrayName );
@@ -1808,13 +1814,13 @@ makeRangeConstructors(const char *name, Oid namespace,
18081814 * If we had an anyrangearray polymorphic type we could use it here,
18091815 * but since each type has its own constructor name there's no need.
18101816 *
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
18121818 * to cast from a range to a multirange.
18131819 */
18141820static void
18151821makeMultirangeConstructors (const char * name , Oid namespace ,
18161822 Oid multirangeOid , Oid rangeOid , Oid rangeArrayOid ,
1817- Oid * castFuncOid )
1823+ Oid * oneArgContructorOid )
18181824{
18191825 ObjectAddress myself ,
18201826 referenced ;
@@ -1904,7 +1910,7 @@ makeMultirangeConstructors(const char *name, Oid namespace,
19041910 /* ditto */
19051911 recordDependencyOn (& myself , & referenced , DEPENDENCY_INTERNAL );
19061912 pfree (argtypes );
1907- * castFuncOid = myself .objectId ;
1913+ * oneArgContructorOid = myself .objectId ;
19081914
19091915 /* n-arg constructor - vararg */
19101916 argtypes = buildoidvector (& rangeArrayOid , 1 );
@@ -1949,6 +1955,76 @@ makeMultirangeConstructors(const char *name, Oid namespace,
19491955 pfree (parameterModes );
19501956}
19511957
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+
19522028/*
19532029 * Find suitable I/O and other support functions for a type.
19542030 *
0 commit comments