diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 91b7674cbb3..6388385edc5 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -19181,29 +19181,6 @@ SELECT NULLIF(value, '(none)') ...
{[1,2)}
-
-
-
-
- unnest
- for multirange
-
- unnest ( anymultirange )
- setof anyrange
-
-
- Expands a multirange into a set of ranges.
- The ranges are read out in storage order (ascending).
-
-
- unnest('{[1,2), [3,4)}'::int4multirange)
-
-
- [1,2)
- [3,4)
-
-
-
diff --git a/doc/src/sgml/rangetypes.sgml b/doc/src/sgml/rangetypes.sgml
index 9ec5510e23a..92ea0e83dab 100644
--- a/doc/src/sgml/rangetypes.sgml
+++ b/doc/src/sgml/rangetypes.sgml
@@ -266,18 +266,6 @@ SELECT '[4,4)'::int4range;
SELECT '{}'::int4multirange;
SELECT '{[3,7)}'::int4multirange;
SELECT '{[3,7), [8,9)}'::int4multirange;
-
-
-
-
- A multirange can be cast to an array of ranges of the same type.
-
-
-
- Examples:
-
-SELECT '{[3,7), [8,9)}'::int4multirange::int4range[];
-SELECT '{[1.0,14.0), [20.0,25.0)}'::nummultirange::numrange[];
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 9ea0ce17e12..58ec65c6afc 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -114,11 +114,7 @@ static void makeRangeConstructors(const char *name, Oid namespace,
Oid rangeOid, Oid subtype);
static void makeMultirangeConstructors(const char *name, Oid namespace,
Oid multirangeOid, Oid rangeOid,
- Oid rangeArrayOid,
- Oid *oneArgContructorOid);
-static void makeMultirangeCasts(const char *name, Oid namespace,
- Oid multirangeOid, Oid rangeOid,
- Oid rangeArrayOid, Oid singleArgContructorOid);
+ Oid rangeArrayOid, Oid *castFuncOid);
static Oid findTypeInputFunction(List *procname, Oid typeOid);
static Oid findTypeOutputFunction(List *procname, Oid typeOid);
static Oid findTypeReceiveFunction(List *procname, Oid typeOid);
@@ -1369,7 +1365,7 @@ DefineRange(CreateRangeStmt *stmt)
ListCell *lc;
ObjectAddress address;
ObjectAddress mltrngaddress PG_USED_FOR_ASSERTS_ONLY;
- Oid singleArgContructorOid;
+ Oid castFuncOid;
/* Convert list of names to a name and namespace */
typeNamespace = QualifiedNameGetCreationNamespace(stmt->typeName,
@@ -1721,12 +1717,10 @@ DefineRange(CreateRangeStmt *stmt)
makeRangeConstructors(typeName, typeNamespace, typoid, rangeSubtype);
makeMultirangeConstructors(multirangeTypeName, typeNamespace,
multirangeOid, typoid, rangeArrayOid,
- &singleArgContructorOid);
+ &castFuncOid);
- /* Create casts for this multirange type */
- makeMultirangeCasts(multirangeTypeName, typeNamespace,
- multirangeOid, typoid, rangeArrayOid,
- singleArgContructorOid);
+ /* Create cast from the range type to its multirange type */
+ CastCreate(typoid, multirangeOid, castFuncOid, 'e', 'f', DEPENDENCY_INTERNAL);
pfree(multirangeTypeName);
pfree(multirangeArrayName);
@@ -1814,13 +1808,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 oneArgContructorOid to the oid of the new constructor that can be used
+ * Sets castFuncOid to the oid of the new constructor that can be used
* to cast from a range to a multirange.
*/
static void
makeMultirangeConstructors(const char *name, Oid namespace,
Oid multirangeOid, Oid rangeOid, Oid rangeArrayOid,
- Oid *oneArgContructorOid)
+ Oid *castFuncOid)
{
ObjectAddress myself,
referenced;
@@ -1910,7 +1904,7 @@ makeMultirangeConstructors(const char *name, Oid namespace,
/* ditto */
recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
pfree(argtypes);
- *oneArgContructorOid = myself.objectId;
+ *castFuncOid = myself.objectId;
/* n-arg constructor - vararg */
argtypes = buildoidvector(&rangeArrayOid, 1);
@@ -1955,76 +1949,6 @@ makeMultirangeConstructors(const char *name, Oid namespace,
pfree(parameterModes);
}
-/*
- * Create casts for the multirange type. The first cast makes multirange from
- * range, and it's based on the single-argument constructor. The second cast
- * makes an array of ranges from multirange.
- */
-static void
-makeMultirangeCasts(const char *name, Oid namespace,
- Oid multirangeOid, Oid rangeOid, Oid rangeArrayOid,
- Oid singleArgContructorOid)
-{
- ObjectAddress myself,
- referenced;
- oidvector *argtypes;
-
- /*
- * Create cast from range to multirange using the existing single-argument
- * constructor procedure.
- */
- CastCreate(rangeOid, multirangeOid, singleArgContructorOid, 'e', 'f',
- DEPENDENCY_INTERNAL);
-
- referenced.classId = TypeRelationId;
- referenced.objectId = multirangeOid;
- referenced.objectSubId = 0;
-
- /* multirange_to_array() function */
- argtypes = buildoidvector(&multirangeOid, 1);
- myself = ProcedureCreate("multirange_to_array", /* name */
- namespace,
- false, /* replace */
- false, /* returns set */
- rangeArrayOid, /* return type */
- BOOTSTRAP_SUPERUSERID, /* proowner */
- INTERNALlanguageId, /* language */
- F_FMGR_INTERNAL_VALIDATOR,
- "multirange_to_array", /* prosrc */
- NULL, /* probin */
- NULL, /* prosqlbody */
- PROKIND_FUNCTION,
- false, /* security_definer */
- false, /* leakproof */
- true, /* isStrict */
- PROVOLATILE_IMMUTABLE, /* volatility */
- PROPARALLEL_SAFE, /* parallel safety */
- argtypes, /* parameterTypes */
- PointerGetDatum(NULL), /* allParameterTypes */
- PointerGetDatum(NULL), /* parameterModes */
- PointerGetDatum(NULL), /* parameterNames */
- NIL, /* parameterDefaults */
- PointerGetDatum(NULL), /* trftypes */
- PointerGetDatum(NULL), /* proconfig */
- InvalidOid, /* prosupport */
- 1.0, /* procost */
- 0.0); /* prorows */
-
- /*
- * Make the multirange_to_array() function internally-dependent on the
- * multirange type so that they go away silently when the type is dropped.
- */
- recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
- pfree(argtypes);
-
- /*
- * Create cast from multirange to the array of ranges using
- * multirange_to_array() function.
- */
- CastCreate(multirangeOid, rangeArrayOid, myself.objectId, 'e', 'f',
- DEPENDENCY_INTERNAL);
-}
-
/*
* Find suitable I/O and other support functions for a type.
*
diff --git a/src/backend/utils/adt/multirangetypes.c b/src/backend/utils/adt/multirangetypes.c
index fbbda4af36d..fbcc27d0726 100644
--- a/src/backend/utils/adt/multirangetypes.c
+++ b/src/backend/utils/adt/multirangetypes.c
@@ -34,7 +34,6 @@
#include "access/tupmacs.h"
#include "common/hashfn.h"
-#include "funcapi.h"
#include "lib/stringinfo.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
@@ -1069,39 +1068,6 @@ multirange_constructor0(PG_FUNCTION_ARGS)
PG_RETURN_MULTIRANGE_P(make_multirange(mltrngtypid, rangetyp, 0, NULL));
}
-/*
- * Cast multirange to an array of ranges.
- */
-Datum
-multirange_to_array(PG_FUNCTION_ARGS)
-{
- ArrayBuildState *astate = NULL;
- MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0);
- TypeCacheEntry *typcache;
- int i;
-
- typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
-
- astate = initArrayResult(typcache->rngtype->type_id,
- CurrentMemoryContext,
- false);
-
- for (i = 0; i < mr->rangeCount; i++)
- {
- RangeType *r;
-
- r = multirange_get_range(typcache->rngtype, mr, i);
- astate = accumArrayResult(astate,
- RangeTypePGetDatum(r),
- false,
- typcache->rngtype->type_id,
- CurrentMemoryContext);
- }
-
- PG_RETURN_ARRAYTYPE_P(makeArrayResult(astate, CurrentMemoryContext));
-}
-
-
/* multirange, multirange -> multirange type functions */
@@ -2679,78 +2645,6 @@ range_merge_from_multirange(PG_FUNCTION_ARGS)
PG_RETURN_RANGE_P(result);
}
-/* Turn multirange into a set of ranges */
-Datum
-multirange_unnest(PG_FUNCTION_ARGS)
-{
- typedef struct
- {
- MultirangeType *mr;
- TypeCacheEntry *typcache;
- int index;
- } multirange_unnest_fctx;
-
- FuncCallContext *funcctx;
- multirange_unnest_fctx *fctx;
- MemoryContext oldcontext;
-
- /* stuff done only on the first call of the function */
- if (SRF_IS_FIRSTCALL())
- {
- MultirangeType *mr;
-
- /* create a function context for cross-call persistence */
- funcctx = SRF_FIRSTCALL_INIT();
-
- /*
- * switch to memory context appropriate for multiple function calls
- */
- oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
-
- /*
- * Get the multirange value and detoast if needed. We can't do this
- * earlier because if we have to detoast, we want the detoasted copy
- * to be in multi_call_memory_ctx, so it will go away when we're done
- * and not before. (If no detoast happens, we assume the originally
- * passed multirange will stick around till then.)
- */
- mr = PG_GETARG_MULTIRANGE_P(0);
-
- /* allocate memory for user context */
- fctx = (multirange_unnest_fctx *) palloc(sizeof(multirange_unnest_fctx));
-
- /* initialize state */
- fctx->mr = mr;
- fctx->index = 0;
- fctx->typcache = lookup_type_cache(MultirangeTypeGetOid(mr),
- TYPECACHE_MULTIRANGE_INFO);
-
- funcctx->user_fctx = fctx;
- MemoryContextSwitchTo(oldcontext);
- }
-
- /* stuff done on every call of the function */
- funcctx = SRF_PERCALL_SETUP();
- fctx = funcctx->user_fctx;
-
- if (fctx->index < fctx->mr->rangeCount)
- {
- RangeType *range;
-
- range = multirange_get_range(fctx->typcache->rngtype,
- fctx->mr,
- fctx->index);
- fctx->index++;
-
- SRF_RETURN_NEXT(funcctx, RangeTypePGetDatum(range));
- }
- else
- {
- /* do when there is no more left */
- SRF_RETURN_DONE(funcctx);
- }
-}
-
/* Hash support */
/* hash a multirange value */
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 7f483936dbc..1b23c7c253b 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 202106152
+#define CATALOG_VERSION_NO 202106151
#endif
diff --git a/src/include/catalog/pg_cast.dat b/src/include/catalog/pg_cast.dat
index d0b37edb605..67f73cb6fb2 100644
--- a/src/include/catalog/pg_cast.dat
+++ b/src/include/catalog/pg_cast.dat
@@ -548,24 +548,4 @@
{ castsource => 'tstzrange', casttarget => 'tstzmultirange',
castfunc => 'tstzmultirange(tstzrange)', castcontext => 'e',
castmethod => 'f' },
-
-# multirange to array
-{ castsource => 'int4multirange', casttarget => '_int4range',
- castfunc => 'multirange_to_array(int4multirange)', castcontext => 'e',
- castmethod => 'f' }
-{ castsource => 'int8multirange', casttarget => '_int8range',
- castfunc => 'multirange_to_array(int8multirange)', castcontext => 'e',
- castmethod => 'f' }
-{ castsource => 'nummultirange', casttarget => '_numrange',
- castfunc => 'multirange_to_array(nummultirange)', castcontext => 'e',
- castmethod => 'f' }
-{ castsource => 'datemultirange', casttarget => '_daterange',
- castfunc => 'multirange_to_array(datemultirange)', castcontext => 'e',
- castmethod => 'f' }
-{ castsource => 'tsmultirange', casttarget => '_tsrange',
- castfunc => 'multirange_to_array(tsmultirange)', castcontext => 'e',
- castmethod => 'f' }
-{ castsource => 'tstzmultirange', casttarget => '_tstzrange',
- castfunc => 'multirange_to_array(tstzmultirange)', castcontext => 'e',
- castmethod => 'f' }
]
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 5af721ee3df..fde251fa4f3 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -10537,29 +10537,6 @@
proname => 'range_intersect_agg', prokind => 'a', proisstrict => 'f',
prorettype => 'anymultirange', proargtypes => 'anymultirange',
prosrc => 'aggregate_dummy' },
-{ oid => '1293', descr => 'expand multirange to set of ranges',
- proname => 'unnest', prorows => '100',
- proretset => 't', prorettype => 'anyrange', proargtypes => 'anymultirange',
- prosrc => 'multirange_unnest' },
-
-{ oid => '4544', descr => 'convert multirange to array of ranges',
- proname => 'multirange_to_array', prorettype => '_int4range',
- proargtypes => 'int4multirange', prosrc => 'multirange_to_array' },
-{ oid => '4545', descr => 'convert multirange to array of ranges',
- proname => 'multirange_to_array', prorettype => '_int8range',
- proargtypes => 'int8multirange', prosrc => 'multirange_to_array' },
-{ oid => '4546', descr => 'convert multirange to array of ranges',
- proname => 'multirange_to_array', prorettype => '_numrange',
- proargtypes => 'nummultirange', prosrc => 'multirange_to_array' },
-{ oid => '4547', descr => 'convert multirange to array of ranges',
- proname => 'multirange_to_array', prorettype => '_daterange',
- proargtypes => 'datemultirange', prosrc => 'multirange_to_array' },
-{ oid => '4548', descr => 'convert multirange to array of ranges',
- proname => 'multirange_to_array', prorettype => '_tsrange',
- proargtypes => 'tsmultirange', prosrc => 'multirange_to_array' },
-{ oid => '4549', descr => 'convert multirange to array of ranges',
- proname => 'multirange_to_array', prorettype => '_tstzrange',
- proargtypes => 'tstzmultirange', prosrc => 'multirange_to_array' },
# date, time, timestamp constructors
{ oid => '3846', descr => 'construct date',
diff --git a/src/test/regress/expected/multirangetypes.out b/src/test/regress/expected/multirangetypes.out
index 7ca2d3f30a9..98ac592127b 100644
--- a/src/test/regress/expected/multirangetypes.out
+++ b/src/test/regress/expected/multirangetypes.out
@@ -322,18 +322,6 @@ select int4range(null, null)::int4multirange;
{(,)}
(1 row)
-select 'empty'::int4range::int4multirange::int4range[];
- int4range
------------
- {}
-(1 row)
-
-select int4multirange(int4range('5', '6'), int4range('1', '2'))::int4range[];
- int4multirange
--------------------
- {"[1,2)","[5,6)"}
-(1 row)
-
select 'empty'::textrange::textmultirange;
textmultirange
----------------
@@ -358,35 +346,6 @@ select textrange(null, null)::textmultirange;
{(,)}
(1 row)
-select textmultirange(textrange('a', 'b'), textrange('d', 'e'))::textrange[];
- textmultirange
--------------------
- {"[a,b)","[d,e)"}
-(1 row)
-
-select 'empty'::textrange::textmultirange::textrange[];
- textrange
------------
- {}
-(1 row)
-
---
--- test unnest(multirange) function
---
-select unnest(int4multirange(int4range('5', '6'), int4range('1', '2')));
- unnest
---------
- [1,2)
- [5,6)
-(2 rows)
-
-select unnest(textmultirange(textrange('a', 'b'), textrange('d', 'e')));
- unnest
---------
- [a,b)
- [d,e)
-(2 rows)
-
--
-- create some test data and test the operators
--
@@ -2769,25 +2728,6 @@ LINE 1: select multirange_of_text(textrange2('a','Z'));
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select multirange_of_text(textrange1('a','Z')) @> 'b'::text;
ERROR: range lower bound must be less than or equal to range upper bound
-select multirange_of_text(textrange1('a','b'), textrange1('d','e'))::textrange1[];
- multirange_of_text
---------------------
- {"[a,b)","[d,e)"}
-(1 row)
-
-select multirange_of_text()::textrange1[];
- multirange_of_text
---------------------
- {}
-(1 row)
-
-select unnest(multirange_of_text(textrange1('a','b'), textrange1('d','e')));
- unnest
---------
- [a,b)
- [d,e)
-(2 rows)
-
select _textrange1(textrange2('a','z')) @> 'b'::text;
?column?
----------
diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index fbcd1934093..562b586d8e0 100644
--- a/src/test/regress/expected/opr_sanity.out
+++ b/src/test/regress/expected/opr_sanity.out
@@ -151,8 +151,6 @@ WHERE p1.oid != p2.oid AND
p2.prosrc NOT LIKE E'range\\_constructor_' AND
p1.prosrc NOT LIKE E'multirange\\_constructor_' AND
p2.prosrc NOT LIKE E'multirange\\_constructor_' AND
- p1.prosrc != 'multirange_to_array' AND
- p2.prosrc != 'multirange_to_array' AND
(p1.prorettype < p2.prorettype)
ORDER BY 1, 2;
prorettype | prorettype
@@ -173,8 +171,6 @@ WHERE p1.oid != p2.oid AND
p2.prosrc NOT LIKE E'range\\_constructor_' AND
p1.prosrc NOT LIKE E'multirange\\_constructor_' AND
p2.prosrc NOT LIKE E'multirange\\_constructor_' AND
- p1.prosrc != 'multirange_to_array' AND
- p2.prosrc != 'multirange_to_array' AND
(p1.proargtypes[0] < p2.proargtypes[0])
ORDER BY 1, 2;
proargtypes | proargtypes
@@ -197,8 +193,6 @@ WHERE p1.oid != p2.oid AND
p2.prosrc NOT LIKE E'range\\_constructor_' AND
p1.prosrc NOT LIKE E'multirange\\_constructor_' AND
p2.prosrc NOT LIKE E'multirange\\_constructor_' AND
- p1.prosrc != 'multirange_to_array' AND
- p2.prosrc != 'multirange_to_array' AND
(p1.proargtypes[1] < p2.proargtypes[1])
ORDER BY 1, 2;
proargtypes | proargtypes
diff --git a/src/test/regress/sql/multirangetypes.sql b/src/test/regress/sql/multirangetypes.sql
index d636e8ca344..3cbebedcd4a 100644
--- a/src/test/regress/sql/multirangetypes.sql
+++ b/src/test/regress/sql/multirangetypes.sql
@@ -72,20 +72,10 @@ select 'empty'::int4range::int4multirange;
select int4range(1, 3)::int4multirange;
select int4range(1, null)::int4multirange;
select int4range(null, null)::int4multirange;
-select 'empty'::int4range::int4multirange::int4range[];
-select int4multirange(int4range('5', '6'), int4range('1', '2'))::int4range[];
select 'empty'::textrange::textmultirange;
select textrange('a', 'c')::textmultirange;
select textrange('a', null)::textmultirange;
select textrange(null, null)::textmultirange;
-select textmultirange(textrange('a', 'b'), textrange('d', 'e'))::textrange[];
-select 'empty'::textrange::textmultirange::textrange[];
-
---
--- test unnest(multirange) function
---
-select unnest(int4multirange(int4range('5', '6'), int4range('1', '2')));
-select unnest(textmultirange(textrange('a', 'b'), textrange('d', 'e')));
--
-- create some test data and test the operators
@@ -631,9 +621,6 @@ create type textrange2 as range(subtype=text, multirange_type_name=_textrange1,
select multirange_of_text(textrange2('a','Z')); -- should fail
select multirange_of_text(textrange1('a','Z')) @> 'b'::text;
-select multirange_of_text(textrange1('a','b'), textrange1('d','e'))::textrange1[];
-select multirange_of_text()::textrange1[];
-select unnest(multirange_of_text(textrange1('a','b'), textrange1('d','e')));
select _textrange1(textrange2('a','z')) @> 'b'::text;
drop type textrange1;
diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql
index 19497625f9a..5a9c4796923 100644
--- a/src/test/regress/sql/opr_sanity.sql
+++ b/src/test/regress/sql/opr_sanity.sql
@@ -127,8 +127,6 @@ WHERE p1.oid != p2.oid AND
p2.prosrc NOT LIKE E'range\\_constructor_' AND
p1.prosrc NOT LIKE E'multirange\\_constructor_' AND
p2.prosrc NOT LIKE E'multirange\\_constructor_' AND
- p1.prosrc != 'multirange_to_array' AND
- p2.prosrc != 'multirange_to_array' AND
(p1.prorettype < p2.prorettype)
ORDER BY 1, 2;
@@ -142,8 +140,6 @@ WHERE p1.oid != p2.oid AND
p2.prosrc NOT LIKE E'range\\_constructor_' AND
p1.prosrc NOT LIKE E'multirange\\_constructor_' AND
p2.prosrc NOT LIKE E'multirange\\_constructor_' AND
- p1.prosrc != 'multirange_to_array' AND
- p2.prosrc != 'multirange_to_array' AND
(p1.proargtypes[0] < p2.proargtypes[0])
ORDER BY 1, 2;
@@ -157,8 +153,6 @@ WHERE p1.oid != p2.oid AND
p2.prosrc NOT LIKE E'range\\_constructor_' AND
p1.prosrc NOT LIKE E'multirange\\_constructor_' AND
p2.prosrc NOT LIKE E'multirange\\_constructor_' AND
- p1.prosrc != 'multirange_to_array' AND
- p2.prosrc != 'multirange_to_array' AND
(p1.proargtypes[1] < p2.proargtypes[1])
ORDER BY 1, 2;