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
2020-12-20 05:20:33 +01:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* multirangetypes.h
|
|
|
|
* Declarations for Postgres multirange types.
|
|
|
|
*
|
|
|
|
*
|
2022-01-08 01:04:57 +01:00
|
|
|
* Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
|
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
2020-12-20 05:20:33 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
|
|
|
* src/include/utils/multirangetypes.h
|
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#ifndef MULTIRANGETYPES_H
|
|
|
|
#define MULTIRANGETYPES_H
|
|
|
|
|
2020-12-29 21:35:38 +01:00
|
|
|
#include "utils/rangetypes.h"
|
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
2020-12-20 05:20:33 +01:00
|
|
|
#include "utils/typcache.h"
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Multiranges are varlena objects, so must meet the varlena convention that
|
|
|
|
* the first int32 of the object contains the total object size in bytes.
|
|
|
|
* Be sure to use VARSIZE() and SET_VARSIZE() to access it, though!
|
|
|
|
*/
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int32 vl_len_; /* varlena header (do not touch directly!) */
|
|
|
|
Oid multirangetypid; /* multirange type's own OID */
|
|
|
|
uint32 rangeCount; /* the number of ranges */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Following the count are the range objects themselves, as ShortRangeType
|
|
|
|
* structs. Note that ranges are varlena too, depending on whether they
|
|
|
|
* have lower/upper bounds and because even their base types can be
|
|
|
|
* varlena. So we can't really index into this list.
|
|
|
|
*/
|
|
|
|
} MultirangeType;
|
|
|
|
|
|
|
|
/* Use these macros in preference to accessing these fields directly */
|
|
|
|
#define MultirangeTypeGetOid(mr) ((mr)->multirangetypid)
|
|
|
|
#define MultirangeIsEmpty(mr) ((mr)->rangeCount == 0)
|
|
|
|
|
|
|
|
/*
|
2022-09-12 19:57:07 +02:00
|
|
|
* fmgr macros for multirange type objects
|
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
2020-12-20 05:20:33 +01:00
|
|
|
*/
|
2022-09-12 19:57:07 +02:00
|
|
|
#define DatumGetMultirangeTypeP(X) ((MultirangeType *) PG_DETOAST_DATUM(X))
|
|
|
|
#define DatumGetMultirangeTypePCopy(X) ((MultirangeType *) PG_DETOAST_DATUM_COPY(X))
|
|
|
|
#define MultirangeTypePGetDatum(X) PointerGetDatum(X)
|
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
2020-12-20 05:20:33 +01:00
|
|
|
#define PG_GETARG_MULTIRANGE_P(n) DatumGetMultirangeTypeP(PG_GETARG_DATUM(n))
|
|
|
|
#define PG_GETARG_MULTIRANGE_P_COPY(n) DatumGetMultirangeTypePCopy(PG_GETARG_DATUM(n))
|
|
|
|
#define PG_RETURN_MULTIRANGE_P(x) return MultirangeTypePGetDatum(x)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* prototypes for functions defined in multirangetypes.c
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* internal versions of the above */
|
2020-12-29 21:35:38 +01:00
|
|
|
extern bool multirange_eq_internal(TypeCacheEntry *rangetyp,
|
|
|
|
const MultirangeType *mr1,
|
|
|
|
const MultirangeType *mr2);
|
|
|
|
extern bool multirange_ne_internal(TypeCacheEntry *rangetyp,
|
|
|
|
const MultirangeType *mr1,
|
|
|
|
const MultirangeType *mr2);
|
|
|
|
extern bool multirange_contains_elem_internal(TypeCacheEntry *rangetyp,
|
|
|
|
const MultirangeType *mr,
|
2022-09-20 22:09:30 +02:00
|
|
|
Datum val);
|
2020-12-29 21:35:38 +01:00
|
|
|
extern bool multirange_contains_range_internal(TypeCacheEntry *rangetyp,
|
|
|
|
const MultirangeType *mr,
|
|
|
|
const RangeType *r);
|
|
|
|
extern bool range_contains_multirange_internal(TypeCacheEntry *rangetyp,
|
|
|
|
const RangeType *r,
|
|
|
|
const MultirangeType *mr);
|
|
|
|
extern bool multirange_contains_multirange_internal(TypeCacheEntry *rangetyp,
|
|
|
|
const MultirangeType *mr1,
|
|
|
|
const MultirangeType *mr2);
|
|
|
|
extern bool range_overlaps_multirange_internal(TypeCacheEntry *rangetyp,
|
|
|
|
const RangeType *r,
|
|
|
|
const MultirangeType *mr);
|
|
|
|
extern bool multirange_overlaps_multirange_internal(TypeCacheEntry *rangetyp,
|
|
|
|
const MultirangeType *mr1,
|
|
|
|
const MultirangeType *mr2);
|
|
|
|
extern bool range_overleft_multirange_internal(TypeCacheEntry *rangetyp,
|
|
|
|
const RangeType *r,
|
|
|
|
const MultirangeType *mr);
|
|
|
|
extern bool range_overright_multirange_internal(TypeCacheEntry *rangetyp,
|
|
|
|
const RangeType *r,
|
|
|
|
const MultirangeType *mr);
|
|
|
|
extern bool range_before_multirange_internal(TypeCacheEntry *rangetyp,
|
|
|
|
const RangeType *r,
|
|
|
|
const MultirangeType *mr);
|
|
|
|
extern bool range_after_multirange_internal(TypeCacheEntry *rangetyp,
|
|
|
|
const RangeType *r,
|
|
|
|
const MultirangeType *mr);
|
|
|
|
extern bool range_adjacent_multirange_internal(TypeCacheEntry *rangetyp,
|
|
|
|
const RangeType *r,
|
|
|
|
const MultirangeType *mr);
|
|
|
|
extern bool multirange_before_multirange_internal(TypeCacheEntry *rangetyp,
|
|
|
|
const MultirangeType *mr1,
|
|
|
|
const MultirangeType *mr2);
|
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
2020-12-20 05:20:33 +01:00
|
|
|
extern MultirangeType *multirange_minus_internal(Oid mltrngtypoid,
|
|
|
|
TypeCacheEntry *rangetyp,
|
|
|
|
int32 range_count1,
|
|
|
|
RangeType **ranges1,
|
|
|
|
int32 range_count2,
|
|
|
|
RangeType **ranges2);
|
|
|
|
extern MultirangeType *multirange_intersect_internal(Oid mltrngtypoid,
|
|
|
|
TypeCacheEntry *rangetyp,
|
|
|
|
int32 range_count1,
|
|
|
|
RangeType **ranges1,
|
|
|
|
int32 range_count2,
|
|
|
|
RangeType **ranges2);
|
|
|
|
|
|
|
|
/* assorted support functions */
|
|
|
|
extern TypeCacheEntry *multirange_get_typcache(FunctionCallInfo fcinfo,
|
|
|
|
Oid mltrngtypid);
|
|
|
|
extern void multirange_deserialize(TypeCacheEntry *rangetyp,
|
2022-09-20 22:09:30 +02:00
|
|
|
const MultirangeType *multirange,
|
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
2020-12-20 05:20:33 +01:00
|
|
|
int32 *range_count,
|
|
|
|
RangeType ***ranges);
|
|
|
|
extern MultirangeType *make_multirange(Oid mltrngtypoid,
|
2022-09-20 22:09:30 +02:00
|
|
|
TypeCacheEntry *rangetyp,
|
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
2020-12-20 05:20:33 +01:00
|
|
|
int32 range_count, RangeType **ranges);
|
|
|
|
extern MultirangeType *make_empty_multirange(Oid mltrngtypoid,
|
|
|
|
TypeCacheEntry *rangetyp);
|
|
|
|
extern void multirange_get_bounds(TypeCacheEntry *rangetyp,
|
|
|
|
const MultirangeType *multirange,
|
|
|
|
uint32 i,
|
|
|
|
RangeBound *lower, RangeBound *upper);
|
|
|
|
extern RangeType *multirange_get_range(TypeCacheEntry *rangetyp,
|
|
|
|
const MultirangeType *multirange, int i);
|
2020-12-29 21:36:43 +01:00
|
|
|
extern RangeType *multirange_get_union_range(TypeCacheEntry *rangetyp,
|
|
|
|
const MultirangeType *mr);
|
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
2020-12-20 05:20:33 +01:00
|
|
|
|
|
|
|
#endif /* MULTIRANGETYPES_H */
|