PostgreSQL Source Code git master
Loading...
Searching...
No Matches
multirangetypes.h File Reference
#include "utils/rangetypes.h"
#include "utils/typcache.h"
Include dependency graph for multirangetypes.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  MultirangeType
 

Macros

#define MultirangeTypeGetOid(mr)   ((mr)->multirangetypid)
 
#define MultirangeIsEmpty(mr)   ((mr)->rangeCount == 0)
 
#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)
 

Functions

static MultirangeTypeDatumGetMultirangeTypeP (Datum X)
 
static MultirangeTypeDatumGetMultirangeTypePCopy (Datum X)
 
static Datum MultirangeTypePGetDatum (const MultirangeType *X)
 
bool multirange_eq_internal (TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
 
bool multirange_ne_internal (TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
 
bool multirange_contains_elem_internal (TypeCacheEntry *rangetyp, const MultirangeType *mr, Datum val)
 
bool multirange_contains_range_internal (TypeCacheEntry *rangetyp, const MultirangeType *mr, const RangeType *r)
 
bool range_contains_multirange_internal (TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
 
bool multirange_contains_multirange_internal (TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
 
bool range_overlaps_multirange_internal (TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
 
bool multirange_overlaps_multirange_internal (TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
 
bool range_overleft_multirange_internal (TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
 
bool range_overright_multirange_internal (TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
 
bool range_before_multirange_internal (TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
 
bool range_after_multirange_internal (TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
 
bool range_adjacent_multirange_internal (TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
 
bool multirange_before_multirange_internal (TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
 
MultirangeTypemultirange_minus_internal (Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count1, RangeType **ranges1, int32 range_count2, RangeType **ranges2)
 
MultirangeTypemultirange_intersect_internal (Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count1, RangeType **ranges1, int32 range_count2, RangeType **ranges2)
 
TypeCacheEntrymultirange_get_typcache (FunctionCallInfo fcinfo, Oid mltrngtypid)
 
void multirange_deserialize (TypeCacheEntry *rangetyp, const MultirangeType *multirange, int32 *range_count, RangeType ***ranges)
 
MultirangeTypemake_multirange (Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
 
MultirangeTypemake_empty_multirange (Oid mltrngtypoid, TypeCacheEntry *rangetyp)
 
void multirange_get_bounds (TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
 
RangeTypemultirange_get_range (TypeCacheEntry *rangetyp, const MultirangeType *multirange, int i)
 
RangeTypemultirange_get_union_range (TypeCacheEntry *rangetyp, const MultirangeType *mr)
 

Macro Definition Documentation

◆ MultirangeIsEmpty

#define MultirangeIsEmpty (   mr)    ((mr)->rangeCount == 0)

Definition at line 42 of file multirangetypes.h.

◆ MultirangeTypeGetOid

#define MultirangeTypeGetOid (   mr)    ((mr)->multirangetypid)

Definition at line 41 of file multirangetypes.h.

◆ PG_GETARG_MULTIRANGE_P

#define PG_GETARG_MULTIRANGE_P (   n)    DatumGetMultirangeTypeP(PG_GETARG_DATUM(n))

Definition at line 65 of file multirangetypes.h.

◆ PG_GETARG_MULTIRANGE_P_COPY

#define PG_GETARG_MULTIRANGE_P_COPY (   n)    DatumGetMultirangeTypePCopy(PG_GETARG_DATUM(n))

Definition at line 66 of file multirangetypes.h.

◆ PG_RETURN_MULTIRANGE_P

#define PG_RETURN_MULTIRANGE_P (   x)    return MultirangeTypePGetDatum(x)

Definition at line 67 of file multirangetypes.h.

Function Documentation

◆ DatumGetMultirangeTypeP()

static MultirangeType * DatumGetMultirangeTypeP ( Datum  X)
inlinestatic

Definition at line 48 of file multirangetypes.h.

49{
51}
#define PG_DETOAST_DATUM(datum)
Definition fmgr.h:240
static int fb(int x)

References fb(), and PG_DETOAST_DATUM.

Referenced by compute_range_stats(), ExecWithoutOverlapsNotEmpty(), multirange_gist_compress(), multirange_gist_consistent(), multirangesel(), and range_gist_consistent().

◆ DatumGetMultirangeTypePCopy()

static MultirangeType * DatumGetMultirangeTypePCopy ( Datum  X)
inlinestatic

Definition at line 54 of file multirangetypes.h.

55{
57}
#define PG_DETOAST_DATUM_COPY(datum)
Definition fmgr.h:242

References fb(), and PG_DETOAST_DATUM_COPY.

◆ make_empty_multirange()

MultirangeType * make_empty_multirange ( Oid  mltrngtypoid,
TypeCacheEntry rangetyp 
)
extern

Definition at line 853 of file multirangetypes.c.

854{
856}
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)

References fb(), and make_multirange().

Referenced by multirange_intersect().

◆ make_multirange()

MultirangeType * make_multirange ( Oid  mltrngtypoid,
TypeCacheEntry rangetyp,
int32  range_count,
RangeType **  ranges 
)
extern

Definition at line 651 of file multirangetypes.c.

653{
655 Size size;
656
657 /* Sort and merge input ranges. */
659
660 /* Note: zero-fill is required here, just as in heap tuples */
662 multirange = palloc0(size);
663 SET_VARSIZE(multirange, size);
664
665 /* Now fill in the datum */
666 multirange->multirangetypid = mltrngtypoid;
667 multirange->rangeCount = range_count;
668
670
671 return multirange;
672}
size_t Size
Definition c.h:619
void * palloc0(Size size)
Definition mcxt.c:1417
static int32 multirange_canonicalize(TypeCacheEntry *rangetyp, int32 input_range_count, RangeType **ranges)
static Size multirange_size_estimate(TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
static void write_multirange_data(MultirangeType *multirange, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
static void SET_VARSIZE(void *PTR, Size len)
Definition varatt.h:432

References fb(), multirange_canonicalize(), multirange_size_estimate(), palloc0(), SET_VARSIZE(), and write_multirange_data().

Referenced by make_empty_multirange(), multirange_constructor0(), multirange_constructor1(), multirange_constructor2(), multirange_in(), multirange_intersect_internal(), multirange_minus_internal(), multirange_recv(), multirange_union(), multirangesel(), and range_agg_finalfn().

◆ multirange_before_multirange_internal()

bool multirange_before_multirange_internal ( TypeCacheEntry rangetyp,
const MultirangeType mr1,
const MultirangeType mr2 
)
extern

Definition at line 2499 of file multirangetypes.c.

2502{
2504 upper1,
2505 lower2,
2506 upper2;
2507
2509 return false;
2510
2511 multirange_get_bounds(rangetyp, mr1, mr1->rangeCount - 1,
2512 &lower1, &upper1);
2514 &lower2, &upper2);
2515
2516 return (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0);
2517}
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define MultirangeIsEmpty(mr)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)

References fb(), multirange_get_bounds(), MultirangeIsEmpty, and range_cmp_bounds().

Referenced by multirange_after_multirange(), and multirange_before_multirange().

◆ multirange_contains_elem_internal()

bool multirange_contains_elem_internal ( TypeCacheEntry rangetyp,
const MultirangeType mr,
Datum  val 
)
extern

Definition at line 1783 of file multirangetypes.c.

1785{
1786 if (MultirangeIsEmpty(mr))
1787 return false;
1788
1791}
long val
Definition informix.c:689
static bool multirange_bsearch_match(TypeCacheEntry *typcache, const MultirangeType *mr, void *key, multirange_bsearch_comparison cmp_func)
static int multirange_elem_bsearch_comparison(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)

References fb(), multirange_bsearch_match(), multirange_elem_bsearch_comparison(), MultirangeIsEmpty, and val.

Referenced by elem_contained_by_multirange(), and multirange_contains_elem().

◆ multirange_contains_multirange_internal()

bool multirange_contains_multirange_internal ( TypeCacheEntry rangetyp,
const MultirangeType mr1,
const MultirangeType mr2 
)
extern

Definition at line 2341 of file multirangetypes.c.

2344{
2345 int32 range_count1 = mr1->rangeCount;
2346 int32 range_count2 = mr2->rangeCount;
2347 int i1,
2348 i2;
2350 upper1,
2351 lower2,
2352 upper2;
2353
2354 /*
2355 * We follow the same logic for empties as ranges: - an empty multirange
2356 * contains an empty range/multirange. - an empty multirange can't contain
2357 * any other range/multirange. - an empty multirange is contained by any
2358 * other range/multirange.
2359 */
2360
2361 if (range_count2 == 0)
2362 return true;
2363 if (range_count1 == 0)
2364 return false;
2365
2366 /*
2367 * Every range in mr2 must be contained by some range in mr1. To avoid
2368 * O(n^2) we walk through both ranges in tandem.
2369 */
2370 i1 = 0;
2372 for (i2 = 0; i2 < range_count2; i2++)
2373 {
2375
2376 /* Discard r1s while r1 << r2 */
2377 while (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0)
2378 {
2379 if (++i1 >= range_count1)
2380 return false;
2382 }
2383
2384 /*
2385 * If r1 @> r2, go to the next r2, otherwise return false (since every
2386 * r1[n] and r1[n+1] must have a gap). Note this will give weird
2387 * answers if you don't canonicalize, e.g. with a custom
2388 * int2multirange {[1,1], [2,2]} there is a "gap". But that is
2389 * consistent with other range operators, e.g. '[1,1]'::int2range -|-
2390 * '[2,2]'::int2range is false.
2391 */
2393 &lower2, &upper2))
2394 return false;
2395 }
2396
2397 /* All ranges in mr2 are satisfied */
2398 return true;
2399}
int32_t int32
Definition c.h:542
static bool range_bounds_contains(TypeCacheEntry *typcache, RangeBound *lower1, RangeBound *upper1, RangeBound *lower2, RangeBound *upper2)

References fb(), multirange_get_bounds(), range_bounds_contains(), and range_cmp_bounds().

Referenced by multirange_contained_by_multirange(), and multirange_contains_multirange().

◆ multirange_contains_range_internal()

bool multirange_contains_range_internal ( TypeCacheEntry rangetyp,
const MultirangeType mr,
const RangeType r 
)
extern

Definition at line 1877 of file multirangetypes.c.

1880{
1881 RangeBound bounds[2];
1882 bool empty;
1883
1884 /*
1885 * Every multirange contains an infinite number of empty ranges, even an
1886 * empty one.
1887 */
1888 if (RangeIsEmpty(r))
1889 return true;
1890
1891 if (MultirangeIsEmpty(mr))
1892 return false;
1893
1894 range_deserialize(rangetyp, r, &bounds[0], &bounds[1], &empty);
1895 Assert(!empty);
1896
1899}
#define Assert(condition)
Definition c.h:873
static int multirange_range_contains_bsearch_comparison(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
#define RangeIsEmpty(r)
Definition rangetypes.h:55

References Assert, fb(), multirange_bsearch_match(), multirange_range_contains_bsearch_comparison(), MultirangeIsEmpty, range_deserialize(), and RangeIsEmpty.

Referenced by multirange_contains_range(), range_contained_by_multirange(), and range_gist_consistent_leaf_multirange().

◆ multirange_deserialize()

void multirange_deserialize ( TypeCacheEntry rangetyp,
const MultirangeType multirange,
int32 range_count,
RangeType ***  ranges 
)
extern

Definition at line 831 of file multirangetypes.c.

834{
835 *range_count = multirange->rangeCount;
836
837 /* Convert each ShortRangeType into a RangeType */
838 if (*range_count > 0)
839 {
840 int i;
841
842 *ranges = palloc_array(RangeType *, *range_count);
843 for (i = 0; i < *range_count; i++)
845 }
846 else
847 {
848 *ranges = NULL;
849 }
850}
#define palloc_array(type, count)
Definition fe_memutils.h:76
int i
Definition isn.c:77
RangeType * multirange_get_range(TypeCacheEntry *rangetyp, const MultirangeType *multirange, int i)

References fb(), i, multirange_get_range(), and palloc_array.

Referenced by multirange_agg_transfn(), multirange_intersect(), multirange_intersect_agg_transfn(), multirange_minus(), multirange_minus_multi(), multirange_out(), multirange_send(), and multirange_union().

◆ multirange_eq_internal()

bool multirange_eq_internal ( TypeCacheEntry rangetyp,
const MultirangeType mr1,
const MultirangeType mr2 
)
extern

Definition at line 1940 of file multirangetypes.c.

1943{
1946 int32 i;
1948 upper1,
1949 lower2,
1950 upper2;
1951
1952 /* Different types should be prevented by ANYMULTIRANGE matching rules */
1954 elog(ERROR, "multirange types do not match");
1955
1956 range_count_1 = mr1->rangeCount;
1957 range_count_2 = mr2->rangeCount;
1958
1960 return false;
1961
1962 for (i = 0; i < range_count_1; i++)
1963 {
1966
1967 if (range_cmp_bounds(rangetyp, &lower1, &lower2) != 0 ||
1969 return false;
1970 }
1971
1972 return true;
1973}
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define MultirangeTypeGetOid(mr)

References elog, ERROR, fb(), i, multirange_get_bounds(), MultirangeTypeGetOid, and range_cmp_bounds().

Referenced by multirange_eq(), and multirange_ne_internal().

◆ multirange_get_bounds()

void multirange_get_bounds ( TypeCacheEntry rangetyp,
const MultirangeType multirange,
uint32  i,
RangeBound lower,
RangeBound upper 
)
extern

Definition at line 749 of file multirangetypes.c.

752{
753 uint32 offset;
754 uint8 flags;
755 const char *ptr;
756 int16 typlen = rangetyp->rngelemtype->typlen;
757 char typalign = rangetyp->rngelemtype->typalign;
758 bool typbyval = rangetyp->rngelemtype->typbyval;
759 Datum lbound;
761
762 Assert(i < multirange->rangeCount);
763
767
768 /* multirange can't contain empty ranges */
769 Assert((flags & RANGE_EMPTY) == 0);
770
771 /* fetch lower bound, if any */
772 if (RANGE_HAS_LBOUND(flags))
773 {
774 /* att_align_pointer cannot be necessary here */
775 lbound = fetch_att(ptr, typbyval, typlen);
776 ptr = (char *) att_addlength_pointer(ptr, typlen, ptr);
777 }
778 else
779 lbound = (Datum) 0;
780
781 /* fetch upper bound, if any */
782 if (RANGE_HAS_UBOUND(flags))
783 {
784 ptr = (char *) att_align_pointer(ptr, typalign, typlen, ptr);
785 ubound = fetch_att(ptr, typbyval, typlen);
786 /* no need for att_addlength_pointer */
787 }
788 else
789 ubound = (Datum) 0;
790
791 /* emit results */
792 lower->val = lbound;
793 lower->infinite = (flags & RANGE_LB_INF) != 0;
794 lower->inclusive = (flags & RANGE_LB_INC) != 0;
795 lower->lower = true;
796
797 upper->val = ubound;
798 upper->infinite = (flags & RANGE_UB_INF) != 0;
799 upper->inclusive = (flags & RANGE_UB_INC) != 0;
800 upper->lower = false;
801}
uint8_t uint8
Definition c.h:544
int16_t int16
Definition c.h:541
uint32_t uint32
Definition c.h:546
#define MultirangeGetFlagsPtr(mr)
static uint32 multirange_get_bounds_offset(const MultirangeType *multirange, int32 i)
#define MultirangeGetBoundariesPtr(mr, align)
Datum lower(PG_FUNCTION_ARGS)
Datum upper(PG_FUNCTION_ARGS)
char typalign
Definition pg_type.h:176
uint64_t Datum
Definition postgres.h:70
#define RANGE_HAS_UBOUND(flags)
Definition rangetypes.h:51
#define RANGE_UB_INC
Definition rangetypes.h:40
#define RANGE_LB_INC
Definition rangetypes.h:39
#define RANGE_UB_INF
Definition rangetypes.h:42
#define RANGE_EMPTY
Definition rangetypes.h:38
#define RANGE_HAS_LBOUND(flags)
Definition rangetypes.h:47
#define RANGE_LB_INF
Definition rangetypes.h:41
#define att_align_pointer(cur_offset, attalign, attlen, attptr)
Definition tupmacs.h:150
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition tupmacs.h:209
static Datum fetch_att(const void *T, bool attbyval, int attlen)
Definition tupmacs.h:50

References Assert, att_addlength_pointer, att_align_pointer, fb(), fetch_att(), i, lower(), multirange_get_bounds_offset(), MultirangeGetBoundariesPtr, MultirangeGetFlagsPtr, RANGE_EMPTY, RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, RANGE_LB_INC, RANGE_LB_INF, RANGE_UB_INC, RANGE_UB_INF, typalign, and upper().

Referenced by calc_hist_selectivity(), compute_range_stats(), hash_multirange(), hash_multirange_extended(), multirange_adjacent_multirange(), multirange_before_multirange_internal(), multirange_bsearch_match(), multirange_cmp(), multirange_contains_multirange_internal(), multirange_eq_internal(), multirange_get_union_range(), multirange_lower(), multirange_lower_inc(), multirange_lower_inf(), multirange_overlaps_multirange_internal(), multirange_overleft_multirange(), multirange_overleft_range(), multirange_overright_multirange(), multirange_overright_range(), multirange_union_range_equal(), multirange_upper(), multirange_upper_inc(), multirange_upper_inf(), range_adjacent_multirange_internal(), range_after_multirange_internal(), range_before_multirange_internal(), range_contains_multirange_internal(), range_merge_from_multirange(), range_overleft_multirange_internal(), and range_overright_multirange_internal().

◆ multirange_get_range()

RangeType * multirange_get_range ( TypeCacheEntry rangetyp,
const MultirangeType multirange,
int  i 
)
extern

Definition at line 700 of file multirangetypes.c.

702{
703 uint32 offset;
704 uint8 flags;
705 const char *begin;
706 char *ptr;
707 int16 typlen = rangetyp->rngelemtype->typlen;
708 char typalign = rangetyp->rngelemtype->typalign;
709 uint32 len;
711
712 Assert(i < multirange->rangeCount);
713
716 begin = ptr = MultirangeGetBoundariesPtr(multirange, typalign) + offset;
717
718 /*
719 * Calculate the size of bound values. In principle, we could get offset
720 * of the next range bound values and calculate accordingly. But range
721 * bound values are aligned, so we have to walk the values to get the
722 * exact size.
723 */
724 if (RANGE_HAS_LBOUND(flags))
725 ptr = (char *) att_addlength_pointer(ptr, typlen, ptr);
726 if (RANGE_HAS_UBOUND(flags))
727 {
728 ptr = (char *) att_align_pointer(ptr, typalign, typlen, ptr);
729 ptr = (char *) att_addlength_pointer(ptr, typlen, ptr);
730 }
731 len = (ptr - begin) + sizeof(RangeType) + sizeof(uint8);
732
733 range = palloc0(len);
735 range->rangetypid = rangetyp->type_id;
736
737 memcpy(range + 1, begin, ptr - begin);
738 *((uint8 *) (range + 1) + (ptr - begin)) = flags;
739
740 return range;
741}
const void size_t len
static struct cvec * range(struct vars *v, chr a, chr b, int cases)

References Assert, att_addlength_pointer, att_align_pointer, fb(), i, len, multirange_get_bounds_offset(), MultirangeGetBoundariesPtr, MultirangeGetFlagsPtr, palloc0(), range(), RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, SET_VARSIZE(), and typalign.

Referenced by multirange_deserialize(), multirange_unnest(), and range_merge_from_multirange().

◆ multirange_get_typcache()

TypeCacheEntry * multirange_get_typcache ( FunctionCallInfo  fcinfo,
Oid  mltrngtypid 
)
extern

Definition at line 551 of file multirangetypes.c.

552{
553 TypeCacheEntry *typcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
554
555 if (typcache == NULL ||
556 typcache->type_id != mltrngtypid)
557 {
559 if (typcache->rngtype == NULL)
560 elog(ERROR, "type %u is not a multirange type", mltrngtypid);
561 fcinfo->flinfo->fn_extra = typcache;
562 }
563
564 return typcache;
565}
void * fn_extra
Definition fmgr.h:64
FmgrInfo * flinfo
Definition fmgr.h:87
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition typcache.c:386
#define TYPECACHE_MULTIRANGE_INFO
Definition typcache.h:154

References elog, ERROR, fb(), FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_extra, lookup_type_cache(), TypeCacheEntry::rngtype, TypeCacheEntry::type_id, and TYPECACHE_MULTIRANGE_INFO.

Referenced by elem_contained_by_multirange(), hash_multirange(), hash_multirange_extended(), multirange_adjacent_multirange(), multirange_adjacent_range(), multirange_after_multirange(), multirange_after_range(), multirange_agg_transfn(), multirange_before_multirange(), multirange_before_range(), multirange_cmp(), multirange_constructor0(), multirange_constructor1(), multirange_constructor2(), multirange_contained_by_multirange(), multirange_contained_by_range(), multirange_contains_elem(), multirange_contains_multirange(), multirange_contains_range(), multirange_eq(), multirange_gist_compress(), multirange_intersect(), multirange_intersect_agg_transfn(), multirange_lower(), multirange_lower_inc(), multirange_lower_inf(), multirange_minus(), multirange_ne(), multirange_overlaps_multirange(), multirange_overlaps_range(), multirange_overleft_multirange(), multirange_overleft_range(), multirange_overright_multirange(), multirange_overright_range(), multirange_typanalyze(), multirange_union(), multirange_upper(), multirange_upper_inc(), multirange_upper_inf(), multirangesel(), range_adjacent_multirange(), range_after_multirange(), range_agg_finalfn(), range_before_multirange(), range_contained_by_multirange(), range_contains_multirange(), range_merge_from_multirange(), range_overlaps_multirange(), range_overleft_multirange(), and range_overright_multirange().

◆ multirange_get_union_range()

RangeType * multirange_get_union_range ( TypeCacheEntry rangetyp,
const MultirangeType mr 
)
extern

Definition at line 807 of file multirangetypes.c.

809{
811 upper,
812 tmp;
813
816
818 multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1, &tmp, &upper);
819
820 return make_range(rangetyp, &lower, &upper, false, NULL);
821}
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty, struct Node *escontext)
RangeType * make_empty_range(TypeCacheEntry *typcache)

References fb(), lower(), make_empty_range(), make_range(), multirange_get_bounds(), MultirangeIsEmpty, and upper().

Referenced by multirange_gist_compress().

◆ multirange_intersect_internal()

MultirangeType * multirange_intersect_internal ( Oid  mltrngtypoid,
TypeCacheEntry rangetyp,
int32  range_count1,
RangeType **  ranges1,
int32  range_count2,
RangeType **  ranges2 
)
extern

Definition at line 1336 of file multirangetypes.c.

1339{
1340 RangeType *r1;
1341 RangeType *r2;
1344 int32 i1;
1345 int32 i2;
1346
1347 if (range_count1 == 0 || range_count2 == 0)
1349
1350 /*-----------------------------------------------
1351 * Worst case is a stitching pattern like this:
1352 *
1353 * mr1: --- --- --- ---
1354 * mr2: --- --- ---
1355 * mr3: - - - - - -
1356 *
1357 * That seems to be range_count1 + range_count2 - 1,
1358 * but one extra won't hurt.
1359 *-----------------------------------------------
1360 */
1362 range_count3 = 0;
1363
1364 /*
1365 * For each range in mr1, keep intersecting until the ranges in mr2 have
1366 * passed it. The parallel progress through mr1 and mr2 is similar to
1367 * multirange_minus_multirange_internal, but we don't have to assign back
1368 * to r1.
1369 */
1370 r2 = ranges2[0];
1371 for (i1 = 0, i2 = 0; i1 < range_count1; i1++)
1372 {
1373 r1 = ranges1[i1];
1374
1375 /* Discard r2s while r2 << r1 */
1376 while (r2 != NULL && range_before_internal(rangetyp, r2, r1))
1377 {
1378 r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1379 }
1380
1381 while (r2 != NULL)
1382 {
1384 {
1385 /* Keep the overlapping part */
1387
1388 /* If we "used up" all of r2, go to the next one... */
1390 r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1391
1392 /* ...otherwise go to the next r1 */
1393 else
1394 break;
1395 }
1396 else
1397 /* We're past r1, so move to the next one */
1398 break;
1399 }
1400
1401 /* If we're out of r2s, there can be no more intersections */
1402 if (r2 == NULL)
1403 break;
1404 }
1405
1407}
bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition rangetypes.c:845
bool range_before_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition rangetypes.c:668
RangeType * range_intersect_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
bool range_overleft_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition rangetypes.c:891

References fb(), make_multirange(), palloc0(), range_before_internal(), range_intersect_internal(), range_overlaps_internal(), and range_overleft_internal().

Referenced by multirange_intersect(), and multirange_intersect_agg_transfn().

◆ multirange_minus_internal()

MultirangeType * multirange_minus_internal ( Oid  mltrngtypoid,
TypeCacheEntry rangetyp,
int32  range_count1,
RangeType **  ranges1,
int32  range_count2,
RangeType **  ranges2 
)
extern

Definition at line 1149 of file multirangetypes.c.

1152{
1153 RangeType *r1;
1154 RangeType *r2;
1157 int32 i1;
1158 int32 i2;
1159
1160 /*
1161 * Worst case: every range in ranges1 makes a different cut to some range
1162 * in ranges2.
1163 */
1165 range_count3 = 0;
1166
1167 /*
1168 * For each range in mr1, keep subtracting until it's gone or the ranges
1169 * in mr2 have passed it. After a subtraction we assign what's left back
1170 * to r1. The parallel progress through mr1 and mr2 is similar to
1171 * multirange_overlaps_multirange_internal.
1172 */
1173 r2 = ranges2[0];
1174 for (i1 = 0, i2 = 0; i1 < range_count1; i1++)
1175 {
1176 r1 = ranges1[i1];
1177
1178 /* Discard r2s while r2 << r1 */
1179 while (r2 != NULL && range_before_internal(rangetyp, r2, r1))
1180 {
1181 r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1182 }
1183
1184 while (r2 != NULL)
1185 {
1187 {
1188 /*
1189 * If r2 takes a bite out of the middle of r1, we need two
1190 * outputs
1191 */
1192 range_count3++;
1193 r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1194 }
1196 {
1197 /*
1198 * If r2 overlaps r1, replace r1 with r1 - r2.
1199 */
1201
1202 /*
1203 * If r2 goes past r1, then we need to stay with it, in case
1204 * it hits future r1s. Otherwise we need to keep r1, in case
1205 * future r2s hit it. Since we already subtracted, there's no
1206 * point in using the overright/overleft calls.
1207 */
1209 break;
1210 else
1211 r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1212 }
1213 else
1214 {
1215 /*
1216 * This and all future r2s are past r1, so keep them. Also
1217 * assign whatever is left of r1 to the result.
1218 */
1219 break;
1220 }
1221 }
1222
1223 /*
1224 * Nothing else can remove anything from r1, so keep it. Even if r1 is
1225 * empty here, make_multirange will remove it.
1226 */
1227 ranges3[range_count3++] = r1;
1228 }
1229
1231}
bool range_split_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2, RangeType **output1, RangeType **output2)
RangeType * range_minus_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition rangetypes.c:997

References fb(), make_multirange(), palloc0(), range_before_internal(), range_minus_internal(), range_overlaps_internal(), range_split_internal(), and RangeIsEmpty.

Referenced by multirange_minus(), and multirange_minus_multi().

◆ multirange_ne_internal()

bool multirange_ne_internal ( TypeCacheEntry rangetyp,
const MultirangeType mr1,
const MultirangeType mr2 
)
extern

Definition at line 1990 of file multirangetypes.c.

1993{
1995}
bool multirange_eq_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)

References fb(), and multirange_eq_internal().

Referenced by multirange_ne().

◆ multirange_overlaps_multirange_internal()

bool multirange_overlaps_multirange_internal ( TypeCacheEntry rangetyp,
const MultirangeType mr1,
const MultirangeType mr2 
)
extern

Definition at line 2091 of file multirangetypes.c.

2094{
2097 int32 i1;
2098 int32 i2;
2100 upper1,
2101 lower2,
2102 upper2;
2103
2104 /*
2105 * Empties never overlap, even with empties. (This seems strange since
2106 * they *do* contain each other, but we want to follow how ranges work.)
2107 */
2109 return false;
2110
2111 range_count1 = mr1->rangeCount;
2112 range_count2 = mr2->rangeCount;
2113
2114 /*
2115 * Every range in mr1 gets a chance to overlap with the ranges in mr2, but
2116 * we can use their ordering to avoid O(n^2). This is similar to
2117 * range_overlaps_multirange where r1 : r2 :: mrr : r, but there if we
2118 * don't find an overlap with r we're done, and here if we don't find an
2119 * overlap with r2 we try the next r2.
2120 */
2121 i1 = 0;
2123 for (i1 = 0, i2 = 0; i2 < range_count2; i2++)
2124 {
2126
2127 /* Discard r1s while r1 << r2 */
2128 while (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0)
2129 {
2130 if (++i1 >= range_count1)
2131 return false;
2133 }
2134
2135 /*
2136 * If r1 && r2, we're done, otherwise we failed to find an overlap for
2137 * r2, so go to the next one.
2138 */
2140 return true;
2141 }
2142
2143 /* We looked through all of mr2 without finding an overlap */
2144 return false;
2145}
static bool range_bounds_overlaps(TypeCacheEntry *typcache, RangeBound *lower1, RangeBound *upper1, RangeBound *lower2, RangeBound *upper2)

References fb(), multirange_get_bounds(), MultirangeIsEmpty, range_bounds_overlaps(), and range_cmp_bounds().

Referenced by multirange_overlaps_multirange().

◆ MultirangeTypePGetDatum()

static Datum MultirangeTypePGetDatum ( const MultirangeType X)
inlinestatic

Definition at line 60 of file multirangetypes.h.

61{
62 return PointerGetDatum(X);
63}
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352

References fb(), and PointerGetDatum().

Referenced by multirange_minus_multi().

◆ range_adjacent_multirange_internal()

bool range_adjacent_multirange_internal ( TypeCacheEntry rangetyp,
const RangeType r,
const MultirangeType mr 
)
extern

Definition at line 2546 of file multirangetypes.c.

2549{
2551 upper1,
2552 lower2,
2553 upper2;
2554 bool empty;
2556
2558 return false;
2559
2560 range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2561 Assert(!empty);
2562
2563 range_count = mr->rangeCount;
2565 &lower2, &upper2);
2566
2568 return true;
2569
2570 if (range_count > 1)
2572 &lower2, &upper2);
2573
2575 return true;
2576
2577 return false;
2578}
bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound boundA, RangeBound boundB)
Definition rangetypes.c:761

References Assert, bounds_adjacent(), fb(), multirange_get_bounds(), MultirangeIsEmpty, range_deserialize(), and RangeIsEmpty.

Referenced by multirange_adjacent_range(), range_adjacent_multirange(), range_gist_consistent_int_multirange(), and range_gist_consistent_leaf_multirange().

◆ range_after_multirange_internal()

bool range_after_multirange_internal ( TypeCacheEntry rangetyp,
const RangeType r,
const MultirangeType mr 
)
extern

Definition at line 2521 of file multirangetypes.c.

2524{
2526 upper1,
2527 lower2,
2528 upper2;
2529 bool empty;
2531
2533 return false;
2534
2535 range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2536 Assert(!empty);
2537
2538 range_count = mr->rangeCount;
2540 &lower2, &upper2);
2541
2542 return (range_cmp_bounds(rangetyp, &lower1, &upper2) > 0);
2543}

References Assert, fb(), multirange_get_bounds(), MultirangeIsEmpty, range_cmp_bounds(), range_deserialize(), and RangeIsEmpty.

Referenced by multirange_before_range(), range_after_multirange(), range_gist_consistent_int_multirange(), and range_gist_consistent_leaf_multirange().

◆ range_before_multirange_internal()

bool range_before_multirange_internal ( TypeCacheEntry rangetyp,
const RangeType r,
const MultirangeType mr 
)
extern

Definition at line 2477 of file multirangetypes.c.

2480{
2482 upper1,
2483 lower2,
2484 upper2;
2485 bool empty;
2486
2488 return false;
2489
2490 range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2491 Assert(!empty);
2492
2494
2495 return (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0);
2496}

References Assert, fb(), multirange_get_bounds(), MultirangeIsEmpty, range_cmp_bounds(), range_deserialize(), and RangeIsEmpty.

Referenced by multirange_after_range(), range_before_multirange(), range_gist_consistent_int_multirange(), and range_gist_consistent_leaf_multirange().

◆ range_contains_multirange_internal()

bool range_contains_multirange_internal ( TypeCacheEntry rangetyp,
const RangeType r,
const MultirangeType mr 
)
extern

Definition at line 1905 of file multirangetypes.c.

1908{
1910 upper1,
1911 lower2,
1912 upper2,
1913 tmp;
1914 bool empty;
1915
1916 /*
1917 * Every range contains an infinite number of empty multiranges, even an
1918 * empty one.
1919 */
1920 if (MultirangeIsEmpty(mr))
1921 return true;
1922
1923 if (RangeIsEmpty(r))
1924 return false;
1925
1926 /* Range contains multirange iff it contains its union range. */
1927 range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
1928 Assert(!empty);
1930 multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1, &tmp, &upper2);
1931
1933}

References Assert, fb(), multirange_get_bounds(), MultirangeIsEmpty, range_bounds_contains(), range_deserialize(), and RangeIsEmpty.

Referenced by multirange_contained_by_range(), range_contains_multirange(), range_gist_consistent_int_multirange(), and range_gist_consistent_leaf_multirange().

◆ range_overlaps_multirange_internal()

bool range_overlaps_multirange_internal ( TypeCacheEntry rangetyp,
const RangeType r,
const MultirangeType mr 
)
extern

Definition at line 2069 of file multirangetypes.c.

2072{
2073 RangeBound bounds[2];
2074 bool empty;
2075
2076 /*
2077 * Empties never overlap, even with empties. (This seems strange since
2078 * they *do* contain each other, but we want to follow how ranges work.)
2079 */
2081 return false;
2082
2083 range_deserialize(rangetyp, r, &bounds[0], &bounds[1], &empty);
2084 Assert(!empty);
2085
2088}
static int multirange_range_overlaps_bsearch_comparison(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)

References Assert, fb(), multirange_bsearch_match(), multirange_range_overlaps_bsearch_comparison(), MultirangeIsEmpty, range_deserialize(), and RangeIsEmpty.

Referenced by multirange_overlaps_range(), range_gist_consistent_int_multirange(), range_gist_consistent_leaf_multirange(), and range_overlaps_multirange().

◆ range_overleft_multirange_internal()

bool range_overleft_multirange_internal ( TypeCacheEntry rangetyp,
const RangeType r,
const MultirangeType mr 
)
extern

Definition at line 2149 of file multirangetypes.c.

2152{
2154 upper1,
2155 lower2,
2156 upper2;
2157 bool empty;
2158
2160 return false;
2161
2162 range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2163 Assert(!empty);
2164 multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1,
2165 &lower2, &upper2);
2166
2167 return (range_cmp_bounds(rangetyp, &upper1, &upper2) <= 0);
2168}

References Assert, fb(), multirange_get_bounds(), MultirangeIsEmpty, range_cmp_bounds(), range_deserialize(), and RangeIsEmpty.

Referenced by range_gist_consistent_int_multirange(), range_gist_consistent_leaf_multirange(), and range_overleft_multirange().

◆ range_overright_multirange_internal()

bool range_overright_multirange_internal ( TypeCacheEntry rangetyp,
const RangeType r,
const MultirangeType mr 
)
extern

Definition at line 2233 of file multirangetypes.c.

2236{
2238 upper1,
2239 lower2,
2240 upper2;
2241 bool empty;
2242
2244 return false;
2245
2246 range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2247 Assert(!empty);
2249
2250 return (range_cmp_bounds(rangetyp, &lower1, &lower2) >= 0);
2251}

References Assert, fb(), multirange_get_bounds(), MultirangeIsEmpty, range_cmp_bounds(), range_deserialize(), and RangeIsEmpty.

Referenced by range_gist_consistent_int_multirange(), range_gist_consistent_leaf_multirange(), and range_overright_multirange().