mirror of
https://github.com/postgres/postgres.git
synced 2025-10-15 05:46:52 +03:00
Multirange datatypes
Multiranges are basically sorted arrays of non-overlapping ranges with set-theoretic operations defined over them. Since v14, each range type automatically gets a corresponding multirange datatype. There are both manual and automatic mechanisms for naming multirange types. Once can specify multirange type name using multirange_type_name attribute in CREATE TYPE. Otherwise, a multirange type name is generated automatically. If the range type name contains "range" then we change that to "multirange". Otherwise, we add "_multirange" to the end. Implementation of multiranges comes with a space-efficient internal representation format, which evades extra paddings and duplicated storage of oids. Altogether this format allows fetching a particular range by its index in O(n). Statistic gathering and selectivity estimation are implemented for multiranges. For this purpose, stored multirange is approximated as union range without gaps. This field will likely need improvements in the future. Catversion is bumped. Discussion: https://postgr.es/m/CALNJ-vSUpQ_Y%3DjXvTxt1VYFztaBSsWVXeF1y6gTYQ4bOiWDLgQ%40mail.gmail.com Discussion: https://postgr.es/m/a0b8026459d1e6167933be2104a6174e7d40d0ab.camel%40j-davis.com#fe7218c83b08068bfffb0c5293eceda0 Author: Paul Jungwirth, revised by me Reviewed-by: David Fetter, Corey Huinker, Jeff Davis, Pavel Stehule Reviewed-by: Alvaro Herrera, Tom Lane, Isaac Morland, David G. Johnston Reviewed-by: Zhihong Yu, Alexander Korotkov
This commit is contained in:
62
src/backend/utils/cache/lsyscache.c
vendored
62
src/backend/utils/cache/lsyscache.c
vendored
@@ -2610,6 +2610,16 @@ type_is_range(Oid typid)
|
||||
return (get_typtype(typid) == TYPTYPE_RANGE);
|
||||
}
|
||||
|
||||
/*
|
||||
* type_is_multirange
|
||||
* Returns true if the given type is a multirange type.
|
||||
*/
|
||||
bool
|
||||
type_is_multirange(Oid typid)
|
||||
{
|
||||
return (get_typtype(typid) == TYPTYPE_MULTIRANGE);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_type_category_preferred
|
||||
*
|
||||
@@ -3308,7 +3318,7 @@ get_namespace_name_or_temp(Oid nspid)
|
||||
return get_namespace_name(nspid);
|
||||
}
|
||||
|
||||
/* ---------- PG_RANGE CACHE ---------- */
|
||||
/* ---------- PG_RANGE CACHES ---------- */
|
||||
|
||||
/*
|
||||
* get_range_subtype
|
||||
@@ -3361,6 +3371,56 @@ get_range_collation(Oid rangeOid)
|
||||
return InvalidOid;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_range_multirange
|
||||
* Returns the multirange type of a given range type
|
||||
*
|
||||
* Returns InvalidOid if the type is not a range type.
|
||||
*/
|
||||
Oid
|
||||
get_range_multirange(Oid rangeOid)
|
||||
{
|
||||
HeapTuple tp;
|
||||
|
||||
tp = SearchSysCache1(RANGETYPE, ObjectIdGetDatum(rangeOid));
|
||||
if (HeapTupleIsValid(tp))
|
||||
{
|
||||
Form_pg_range rngtup = (Form_pg_range) GETSTRUCT(tp);
|
||||
Oid result;
|
||||
|
||||
result = rngtup->rngmultitypid;
|
||||
ReleaseSysCache(tp);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
return InvalidOid;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_multirange_range
|
||||
* Returns the range type of a given multirange
|
||||
*
|
||||
* Returns InvalidOid if the type is not a multirange.
|
||||
*/
|
||||
Oid
|
||||
get_multirange_range(Oid multirangeOid)
|
||||
{
|
||||
HeapTuple tp;
|
||||
|
||||
tp = SearchSysCache1(RANGEMULTIRANGE, ObjectIdGetDatum(multirangeOid));
|
||||
if (HeapTupleIsValid(tp))
|
||||
{
|
||||
Form_pg_range rngtup = (Form_pg_range) GETSTRUCT(tp);
|
||||
Oid result;
|
||||
|
||||
result = rngtup->rngtypid;
|
||||
ReleaseSysCache(tp);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
return InvalidOid;
|
||||
}
|
||||
|
||||
/* ---------- PG_INDEX CACHE ---------- */
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user