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 854 of file multirangetypes.c.

855{
857}
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 652 of file multirangetypes.c.

654{
656 Size size;
657
658 /* Sort and merge input ranges. */
660
661 /* Note: zero-fill is required here, just as in heap tuples */
663 multirange = palloc0(size);
664 SET_VARSIZE(multirange, size);
665
666 /* Now fill in the datum */
667 multirange->multirangetypid = mltrngtypoid;
668 multirange->rangeCount = range_count;
669
671
672 return multirange;
673}
size_t Size
Definition c.h:689
void * palloc0(Size size)
Definition mcxt.c:1420
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 2500 of file multirangetypes.c.

2503{
2505 upper1,
2506 lower2,
2507 upper2;
2508
2510 return false;
2511
2512 multirange_get_bounds(rangetyp, mr1, mr1->rangeCount - 1,
2513 &lower1, &upper1);
2515 &lower2, &upper2);
2516
2517 return (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0);
2518}
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 1784 of file multirangetypes.c.

1786{
1787 if (MultirangeIsEmpty(mr))
1788 return false;
1789
1792}
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 2342 of file multirangetypes.c.

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

1881{
1882 RangeBound bounds[2];
1883 bool empty;
1884
1885 /*
1886 * Every multirange contains an infinite number of empty ranges, even an
1887 * empty one.
1888 */
1889 if (RangeIsEmpty(r))
1890 return true;
1891
1892 if (MultirangeIsEmpty(mr))
1893 return false;
1894
1895 range_deserialize(rangetyp, r, &bounds[0], &bounds[1], &empty);
1896 Assert(!empty);
1897
1900}
#define Assert(condition)
Definition c.h:943
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 832 of file multirangetypes.c.

835{
836 *range_count = multirange->rangeCount;
837
838 /* Convert each ShortRangeType into a RangeType */
839 if (*range_count > 0)
840 {
841 int i;
842
843 *ranges = palloc_array(RangeType *, *range_count);
844 for (i = 0; i < *range_count; i++)
846 }
847 else
848 {
849 *ranges = NULL;
850 }
851}
#define palloc_array(type, count)
Definition fe_memutils.h:91
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 1941 of file multirangetypes.c.

1944{
1947 int32 i;
1949 upper1,
1950 lower2,
1951 upper2;
1952
1953 /* Different types should be prevented by ANYMULTIRANGE matching rules */
1955 elog(ERROR, "multirange types do not match");
1956
1957 range_count_1 = mr1->rangeCount;
1958 range_count_2 = mr2->rangeCount;
1959
1961 return false;
1962
1963 for (i = 0; i < range_count_1; i++)
1964 {
1967
1968 if (range_cmp_bounds(rangetyp, &lower1, &lower2) != 0 ||
1970 return false;
1971 }
1972
1973 return true;
1974}
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#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 750 of file multirangetypes.c.

753{
754 uint32 offset;
755 uint8 flags;
756 const char *ptr;
757 int16 typlen = rangetyp->rngelemtype->typlen;
758 char typalign = rangetyp->rngelemtype->typalign;
759 bool typbyval = rangetyp->rngelemtype->typbyval;
760 Datum lbound;
762
763 Assert(i < multirange->rangeCount);
764
768
769 /* multirange can't contain empty ranges */
770 Assert((flags & RANGE_EMPTY) == 0);
771
772 /* fetch lower bound, if any */
773 if (RANGE_HAS_LBOUND(flags))
774 {
775 /* att_align_pointer cannot be necessary here */
776 lbound = fetch_att(ptr, typbyval, typlen);
777 ptr = (char *) att_addlength_pointer(ptr, typlen, ptr);
778 }
779 else
780 lbound = (Datum) 0;
781
782 /* fetch upper bound, if any */
783 if (RANGE_HAS_UBOUND(flags))
784 {
785 ptr = (char *) att_align_pointer(ptr, typalign, typlen, ptr);
786 ubound = fetch_att(ptr, typbyval, typlen);
787 /* no need for att_addlength_pointer */
788 }
789 else
790 ubound = (Datum) 0;
791
792 /* emit results */
793 lower->val = lbound;
794 lower->infinite = (flags & RANGE_LB_INF) != 0;
795 lower->inclusive = (flags & RANGE_LB_INC) != 0;
796 lower->lower = true;
797
798 upper->val = ubound;
799 upper->infinite = (flags & RANGE_UB_INF) != 0;
800 upper->inclusive = (flags & RANGE_UB_INC) != 0;
801 upper->lower = false;
802}
uint8_t uint8
Definition c.h:622
int16_t int16
Definition c.h:619
uint32_t uint32
Definition c.h:624
#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:178
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:372
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition tupmacs.h:431
static Datum fetch_att(const void *T, bool attbyval, int attlen)
Definition tupmacs.h:108

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 701 of file multirangetypes.c.

703{
704 uint32 offset;
705 uint8 flags;
706 const char *begin;
707 char *ptr;
708 int16 typlen = rangetyp->rngelemtype->typlen;
709 char typalign = rangetyp->rngelemtype->typalign;
710 uint32 len;
712
713 Assert(i < multirange->rangeCount);
714
717 begin = ptr = MultirangeGetBoundariesPtr(multirange, typalign) + offset;
718
719 /*
720 * Calculate the size of bound values. In principle, we could get offset
721 * of the next range bound values and calculate accordingly. But range
722 * bound values are aligned, so we have to walk the values to get the
723 * exact size.
724 */
725 if (RANGE_HAS_LBOUND(flags))
726 ptr = (char *) att_addlength_pointer(ptr, typlen, ptr);
727 if (RANGE_HAS_UBOUND(flags))
728 {
729 ptr = (char *) att_align_pointer(ptr, typalign, typlen, ptr);
730 ptr = (char *) att_addlength_pointer(ptr, typlen, ptr);
731 }
732 len = (ptr - begin) + sizeof(RangeType) + sizeof(uint8);
733
734 range = palloc0(len);
736 range->rangetypid = rangetyp->type_id;
737
738 memcpy(range + 1, begin, ptr - begin);
739 *((uint8 *) (range + 1) + (ptr - begin)) = flags;
740
741 return range;
742}
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
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, memcpy(), 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 552 of file multirangetypes.c.

553{
554 TypeCacheEntry *typcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
555
556 if (typcache == NULL ||
557 typcache->type_id != mltrngtypid)
558 {
560 if (typcache->rngtype == NULL)
561 elog(ERROR, "type %u is not a multirange type", mltrngtypid);
562 fcinfo->flinfo->fn_extra = typcache;
563 }
564
565 return typcache;
566}
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:389
#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 808 of file multirangetypes.c.

810{
812 upper,
813 tmp;
814
817
819 multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1, &tmp, &upper);
820
821 return make_range(rangetyp, &lower, &upper, false, NULL);
822}
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 1337 of file multirangetypes.c.

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

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 1150 of file multirangetypes.c.

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

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 1991 of file multirangetypes.c.

1994{
1996}
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 2092 of file multirangetypes.c.

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

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 2547 of file multirangetypes.c.

2550{
2552 upper1,
2553 lower2,
2554 upper2;
2555 bool empty;
2557
2559 return false;
2560
2561 range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2562 Assert(!empty);
2563
2564 range_count = mr->rangeCount;
2566 &lower2, &upper2);
2567
2569 return true;
2570
2571 if (range_count > 1)
2573 &lower2, &upper2);
2574
2576 return true;
2577
2578 return false;
2579}
bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound boundA, RangeBound boundB)
Definition rangetypes.c:763

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 2522 of file multirangetypes.c.

2525{
2527 upper1,
2528 lower2,
2529 upper2;
2530 bool empty;
2532
2534 return false;
2535
2536 range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2537 Assert(!empty);
2538
2539 range_count = mr->rangeCount;
2541 &lower2, &upper2);
2542
2543 return (range_cmp_bounds(rangetyp, &lower1, &upper2) > 0);
2544}

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 2478 of file multirangetypes.c.

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

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 1906 of file multirangetypes.c.

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

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 2070 of file multirangetypes.c.

2073{
2074 RangeBound bounds[2];
2075 bool empty;
2076
2077 /*
2078 * Empties never overlap, even with empties. (This seems strange since
2079 * they *do* contain each other, but we want to follow how ranges work.)
2080 */
2082 return false;
2083
2084 range_deserialize(rangetyp, r, &bounds[0], &bounds[1], &empty);
2085 Assert(!empty);
2086
2089}
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 2150 of file multirangetypes.c.

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

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 2234 of file multirangetypes.c.

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

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().