PostgreSQL Source Code  git master
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 DatumGetMultirangeTypeP(X)   ((MultirangeType *) PG_DETOAST_DATUM(X))
 
#define DatumGetMultirangeTypePCopy(X)   ((MultirangeType *) PG_DETOAST_DATUM_COPY(X))
 
#define MultirangeTypePGetDatum(X)   PointerGetDatum(X)
 
#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

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 elem)
 
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 *range, int32 *range_count, RangeType ***ranges)
 
MultirangeTypemake_multirange (Oid mltrngtypoid, TypeCacheEntry *typcache, 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

◆ DatumGetMultirangeTypeP

#define DatumGetMultirangeTypeP (   X)    ((MultirangeType *) PG_DETOAST_DATUM(X))

◆ DatumGetMultirangeTypePCopy

#define DatumGetMultirangeTypePCopy (   X)    ((MultirangeType *) PG_DETOAST_DATUM_COPY(X))

Definition at line 48 of file multirangetypes.h.

◆ MultirangeIsEmpty

◆ MultirangeTypeGetOid

◆ MultirangeTypePGetDatum

#define MultirangeTypePGetDatum (   X)    PointerGetDatum(X)

Definition at line 49 of file multirangetypes.h.

◆ PG_GETARG_MULTIRANGE_P

◆ PG_GETARG_MULTIRANGE_P_COPY

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

Definition at line 51 of file multirangetypes.h.

◆ PG_RETURN_MULTIRANGE_P

Function Documentation

◆ make_empty_multirange()

MultirangeType* make_empty_multirange ( Oid  mltrngtypoid,
TypeCacheEntry rangetyp 
)

Definition at line 839 of file multirangetypes.c.

References make_multirange().

Referenced by multirange_intersect().

840 {
841  return make_multirange(mltrngtypoid, rangetyp, 0, NULL);
842 }
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)

◆ make_multirange()

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

Definition at line 640 of file multirangetypes.c.

References multirange_canonicalize(), multirange_size_estimate(), MultirangeType::multirangetypid, palloc0(), MultirangeType::rangeCount, 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().

642 {
643  MultirangeType *multirange;
644  Size size;
645 
646  /* Sort and merge input ranges. */
647  range_count = multirange_canonicalize(rangetyp, range_count, ranges);
648 
649  /* Note: zero-fill is required here, just as in heap tuples */
650  size = multirange_size_estimate(rangetyp, range_count, ranges);
651  multirange = palloc0(size);
652  SET_VARSIZE(multirange, size);
653 
654  /* Now fill in the datum */
655  multirange->multirangetypid = mltrngtypoid;
656  multirange->rangeCount = range_count;
657 
658  write_multirange_data(multirange, rangetyp, range_count, ranges);
659 
660  return multirange;
661 }
static void write_multirange_data(MultirangeType *multirange, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
static Size multirange_size_estimate(TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
static int32 multirange_canonicalize(TypeCacheEntry *rangetyp, int32 input_range_count, RangeType **ranges)
void * palloc0(Size size)
Definition: mcxt.c:1093
size_t Size
Definition: c.h:540
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342

◆ multirange_before_multirange_internal()

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

Definition at line 2359 of file multirangetypes.c.

References multirange_get_bounds(), MultirangeIsEmpty, range_cmp_bounds(), and MultirangeType::rangeCount.

Referenced by multirange_after_multirange(), and multirange_before_multirange().

2362 {
2363  RangeBound lower1,
2364  upper1,
2365  lower2,
2366  upper2;
2367 
2368  if (MultirangeIsEmpty(mr1) || MultirangeIsEmpty(mr2))
2369  return false;
2370 
2371  multirange_get_bounds(rangetyp, mr1, mr1->rangeCount - 1,
2372  &lower1, &upper1);
2373  multirange_get_bounds(rangetyp, mr2, 0,
2374  &lower2, &upper2);
2375 
2376  return (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0);
2377 }
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)
Definition: rangetypes.c:1924

◆ multirange_contains_elem_internal()

bool multirange_contains_elem_internal ( TypeCacheEntry rangetyp,
const MultirangeType mr,
Datum  elem 
)

Definition at line 1642 of file multirangetypes.c.

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

Referenced by elem_contained_by_multirange(), and multirange_contains_elem().

1644 {
1645  if (MultirangeIsEmpty(mr))
1646  return false;
1647 
1648  return multirange_bsearch_match(rangetyp, mr, &val,
1650 }
static bool multirange_bsearch_match(TypeCacheEntry *typcache, const MultirangeType *mr, void *key, multirange_bsearch_comparison cmp_func)
#define MultirangeIsEmpty(mr)
static int multirange_elem_bsearch_comparison(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)
long val
Definition: informix.c:664

◆ multirange_contains_multirange_internal()

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

Definition at line 2201 of file multirangetypes.c.

References multirange_get_bounds(), range_bounds_contains(), range_cmp_bounds(), and MultirangeType::rangeCount.

Referenced by multirange_contained_by_multirange(), and multirange_contains_multirange().

2204 {
2205  int32 range_count1 = mr1->rangeCount;
2206  int32 range_count2 = mr2->rangeCount;
2207  int i1,
2208  i2;
2209  RangeBound lower1,
2210  upper1,
2211  lower2,
2212  upper2;
2213 
2214  /*
2215  * We follow the same logic for empties as ranges: - an empty multirange
2216  * contains an empty range/multirange. - an empty multirange can't contain
2217  * any other range/multirange. - an empty multirange is contained by any
2218  * other range/multirange.
2219  */
2220 
2221  if (range_count2 == 0)
2222  return true;
2223  if (range_count1 == 0)
2224  return false;
2225 
2226  /*
2227  * Every range in mr2 must be contained by some range in mr1. To avoid
2228  * O(n^2) we walk through both ranges in tandem.
2229  */
2230  i1 = 0;
2231  multirange_get_bounds(rangetyp, mr1, i1, &lower1, &upper1);
2232  for (i2 = 0; i2 < range_count2; i2++)
2233  {
2234  multirange_get_bounds(rangetyp, mr2, i2, &lower2, &upper2);
2235 
2236  /* Discard r1s while r1 << r2 */
2237  while (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0)
2238  {
2239  if (++i1 >= range_count1)
2240  return false;
2241  multirange_get_bounds(rangetyp, mr1, i1, &lower1, &upper1);
2242  }
2243 
2244  /*
2245  * If r1 @> r2, go to the next r2, otherwise return false (since every
2246  * r1[n] and r1[n+1] must have a gap). Note this will give weird
2247  * answers if you don't canonicalize, e.g. with a custom
2248  * int2multirange {[1,1], [2,2]} there is a "gap". But that is
2249  * consistent with other range operators, e.g. '[1,1]'::int2range -|-
2250  * '[2,2]'::int2range is false.
2251  */
2252  if (!range_bounds_contains(rangetyp, &lower1, &upper1,
2253  &lower2, &upper2))
2254  return false;
2255  }
2256 
2257  /* All ranges in mr2 are satisfied */
2258  return true;
2259 }
signed int int32
Definition: c.h:429
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
static bool range_bounds_contains(TypeCacheEntry *typcache, RangeBound *lower1, RangeBound *upper1, RangeBound *lower2, RangeBound *upper2)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ multirange_contains_range_internal()

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

Definition at line 1736 of file multirangetypes.c.

References Assert, 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().

1739 {
1740  RangeBound bounds[2];
1741  bool empty;
1742 
1743  /*
1744  * Every multirange contains an infinite number of empty ranges, even an
1745  * empty one.
1746  */
1747  if (RangeIsEmpty(r))
1748  return true;
1749 
1750  if (MultirangeIsEmpty(mr))
1751  return false;
1752 
1753  range_deserialize(rangetyp, r, &bounds[0], &bounds[1], &empty);
1754  Assert(!empty);
1755 
1756  return multirange_bsearch_match(rangetyp, mr, bounds,
1758 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
static bool multirange_bsearch_match(TypeCacheEntry *typcache, const MultirangeType *mr, void *key, multirange_bsearch_comparison cmp_func)
static int multirange_range_contains_bsearch_comparison(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)
#define Assert(condition)
Definition: c.h:804
#define MultirangeIsEmpty(mr)
static Ranges * range_deserialize(int maxvalues, SerializedRanges *range)

◆ multirange_deserialize()

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

Definition at line 817 of file multirangetypes.c.

References i, multirange_get_range(), palloc(), and MultirangeType::rangeCount.

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

820 {
821  *range_count = multirange->rangeCount;
822 
823  /* Convert each ShortRangeType into a RangeType */
824  if (*range_count > 0)
825  {
826  int i;
827 
828  *ranges = palloc(*range_count * sizeof(RangeType *));
829  for (i = 0; i < *range_count; i++)
830  (*ranges)[i] = multirange_get_range(rangetyp, multirange, i);
831  }
832  else
833  {
834  *ranges = NULL;
835  }
836 }
RangeType * multirange_get_range(TypeCacheEntry *rangetyp, const MultirangeType *multirange, int i)
void * palloc(Size size)
Definition: mcxt.c:1062
int i

◆ multirange_eq_internal()

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

Definition at line 1799 of file multirangetypes.c.

References elog, ERROR, i, multirange_get_bounds(), MultirangeTypeGetOid, range_cmp_bounds(), and MultirangeType::rangeCount.

Referenced by multirange_eq(), and multirange_ne_internal().

1802 {
1803  int32 range_count_1;
1804  int32 range_count_2;
1805  int32 i;
1806  RangeBound lower1,
1807  upper1,
1808  lower2,
1809  upper2;
1810 
1811  /* Different types should be prevented by ANYMULTIRANGE matching rules */
1812  if (MultirangeTypeGetOid(mr1) != MultirangeTypeGetOid(mr2))
1813  elog(ERROR, "multirange types do not match");
1814 
1815  range_count_1 = mr1->rangeCount;
1816  range_count_2 = mr2->rangeCount;
1817 
1818  if (range_count_1 != range_count_2)
1819  return false;
1820 
1821  for (i = 0; i < range_count_1; i++)
1822  {
1823  multirange_get_bounds(rangetyp, mr1, i, &lower1, &upper1);
1824  multirange_get_bounds(rangetyp, mr2, i, &lower2, &upper2);
1825 
1826  if (range_cmp_bounds(rangetyp, &lower1, &lower2) != 0 ||
1827  range_cmp_bounds(rangetyp, &upper1, &upper2) != 0)
1828  return false;
1829  }
1830 
1831  return true;
1832 }
signed int int32
Definition: c.h:429
#define ERROR
Definition: elog.h:46
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define elog(elevel,...)
Definition: elog.h:232
int i
#define MultirangeTypeGetOid(mr)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ multirange_get_bounds()

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

Definition at line 735 of file multirangetypes.c.

References Assert, att_addlength_pointer, att_align_pointer, fetch_att, i, RangeBound::inclusive, RangeBound::infinite, RangeBound::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, TypeCacheEntry::rngelemtype, TypeCacheEntry::typalign, typalign, TypeCacheEntry::typbyval, TypeCacheEntry::typlen, and RangeBound::val.

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

738 {
739  uint32 offset;
740  uint8 flags;
741  Pointer ptr;
742  int16 typlen = rangetyp->rngelemtype->typlen;
743  char typalign = rangetyp->rngelemtype->typalign;
744  bool typbyval = rangetyp->rngelemtype->typbyval;
745  Datum lbound;
746  Datum ubound;
747 
748  Assert(i < multirange->rangeCount);
749 
750  offset = multirange_get_bounds_offset(multirange, i);
751  flags = MultirangeGetFlagsPtr(multirange)[i];
752  ptr = MultirangeGetBoundariesPtr(multirange, typalign) + offset;
753 
754  /* multirange can't contain empty ranges */
755  Assert((flags & RANGE_EMPTY) == 0);
756 
757  /* fetch lower bound, if any */
758  if (RANGE_HAS_LBOUND(flags))
759  {
760  /* att_align_pointer cannot be necessary here */
761  lbound = fetch_att(ptr, typbyval, typlen);
762  ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr);
763  }
764  else
765  lbound = (Datum) 0;
766 
767  /* fetch upper bound, if any */
768  if (RANGE_HAS_UBOUND(flags))
769  {
770  ptr = (Pointer) att_align_pointer(ptr, typalign, typlen, ptr);
771  ubound = fetch_att(ptr, typbyval, typlen);
772  /* no need for att_addlength_pointer */
773  }
774  else
775  ubound = (Datum) 0;
776 
777  /* emit results */
778  lower->val = lbound;
779  lower->infinite = (flags & RANGE_LB_INF) != 0;
780  lower->inclusive = (flags & RANGE_LB_INC) != 0;
781  lower->lower = true;
782 
783  upper->val = ubound;
784  upper->infinite = (flags & RANGE_UB_INF) != 0;
785  upper->inclusive = (flags & RANGE_UB_INC) != 0;
786  upper->lower = false;
787 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:52
signed short int16
Definition: c.h:428
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:48
#define RANGE_EMPTY
Definition: rangetypes.h:38
unsigned char uint8
Definition: c.h:439
Datum val
Definition: rangetypes.h:64
int16 typlen
Definition: typcache.h:39
#define RANGE_LB_INF
Definition: rangetypes.h:41
bool typbyval
Definition: typcache.h:40
char * Pointer
Definition: c.h:418
char typalign
Definition: pg_type.h:176
bool inclusive
Definition: rangetypes.h:66
#define RANGE_UB_INC
Definition: rangetypes.h:40
unsigned int uint32
Definition: c.h:441
#define MultirangeGetBoundariesPtr(mr, align)
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:176
bool lower
Definition: rangetypes.h:67
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:98
uintptr_t Datum
Definition: postgres.h:411
#define att_align_pointer(cur_offset, attalign, attlen, attptr)
Definition: tupmacs.h:126
static uint32 multirange_get_bounds_offset(const MultirangeType *multirange, int32 i)
#define RANGE_LB_INC
Definition: rangetypes.h:39
#define MultirangeGetFlagsPtr(mr)
#define Assert(condition)
Definition: c.h:804
bool infinite
Definition: rangetypes.h:65
#define RANGE_UB_INF
Definition: rangetypes.h:42
char typalign
Definition: typcache.h:41
#define fetch_att(T, attbyval, attlen)
Definition: tupmacs.h:75
int i

◆ multirange_get_range()

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

Definition at line 689 of file multirangetypes.c.

References Assert, att_addlength_pointer, i, multirange_get_bounds_offset(), MultirangeGetBoundariesPtr, MultirangeGetFlagsPtr, palloc0(), range(), RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, RangeType::rangetypid, TypeCacheEntry::rngelemtype, SET_VARSIZE, TypeCacheEntry::typalign, typalign, TypeCacheEntry::type_id, and TypeCacheEntry::typlen.

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

691 {
692  uint32 offset;
693  uint8 flags;
694  Pointer begin,
695  ptr;
696  int16 typlen = rangetyp->rngelemtype->typlen;
697  char typalign = rangetyp->rngelemtype->typalign;
698  uint32 len;
699  RangeType *range;
700 
701  Assert(i < multirange->rangeCount);
702 
703  offset = multirange_get_bounds_offset(multirange, i);
704  flags = MultirangeGetFlagsPtr(multirange)[i];
705  ptr = begin = MultirangeGetBoundariesPtr(multirange, typalign) + offset;
706 
707  /*
708  * Calculate the size of bound values. In principle, we could get offset
709  * of the next range bound values and calculate accordingly. But range
710  * bound values are aligned, so we have to walk the values to get the
711  * exact size.
712  */
713  if (RANGE_HAS_LBOUND(flags))
714  ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr);
715  if (RANGE_HAS_UBOUND(flags))
716  ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr);
717  len = (ptr - begin) + sizeof(RangeType) + sizeof(uint8);
718 
719  range = palloc0(len);
720  SET_VARSIZE(range, len);
721  range->rangetypid = rangetyp->type_id;
722 
723  memcpy(range + 1, begin, ptr - begin);
724  *((uint8 *) (range + 1) + (ptr - begin)) = flags;
725 
726  return range;
727 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:52
signed short int16
Definition: c.h:428
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:48
unsigned char uint8
Definition: c.h:439
int16 typlen
Definition: typcache.h:39
Oid rangetypid
Definition: rangetypes.h:28
char * Pointer
Definition: c.h:418
char typalign
Definition: pg_type.h:176
unsigned int uint32
Definition: c.h:441
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
#define MultirangeGetBoundariesPtr(mr, align)
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:176
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:98
void * palloc0(Size size)
Definition: mcxt.c:1093
static uint32 multirange_get_bounds_offset(const MultirangeType *multirange, int32 i)
#define MultirangeGetFlagsPtr(mr)
#define Assert(condition)
Definition: c.h:804
char typalign
Definition: typcache.h:41
int i
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342

◆ multirange_get_typcache()

TypeCacheEntry* multirange_get_typcache ( FunctionCallInfo  fcinfo,
Oid  mltrngtypid 
)

Definition at line 542 of file multirangetypes.c.

References elog, ERROR, FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_extra, lookup_type_cache(), TypeCacheEntry::rngtype, MultirangeIOData::typcache, 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_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().

543 {
544  TypeCacheEntry *typcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
545 
546  if (typcache == NULL ||
547  typcache->type_id != mltrngtypid)
548  {
549  typcache = lookup_type_cache(mltrngtypid, TYPECACHE_MULTIRANGE_INFO);
550  if (typcache->rngtype == NULL)
551  elog(ERROR, "type %u is not a multirange type", mltrngtypid);
552  fcinfo->flinfo->fn_extra = (void *) typcache;
553  }
554 
555  return typcache;
556 }
#define TYPECACHE_MULTIRANGE_INFO
Definition: typcache.h:152
#define ERROR
Definition: elog.h:46
FmgrInfo * flinfo
Definition: fmgr.h:87
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:339
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
void * fn_extra
Definition: fmgr.h:64
#define elog(elevel,...)
Definition: elog.h:232

◆ multirange_get_union_range()

RangeType* multirange_get_union_range ( TypeCacheEntry rangetyp,
const MultirangeType mr 
)

Definition at line 793 of file multirangetypes.c.

References lower(), make_empty_range(), make_range(), multirange_get_bounds(), MultirangeIsEmpty, MultirangeType::rangeCount, and upper().

Referenced by multirange_gist_compress().

795 {
797  upper,
798  tmp;
799 
800  if (MultirangeIsEmpty(mr))
801  return make_empty_range(rangetyp);
802 
803  multirange_get_bounds(rangetyp, mr, 0, &lower, &tmp);
804  multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1, &tmp, &upper);
805 
806  return make_range(rangetyp, &lower, &upper, false);
807 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1884
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
RangeType * make_empty_range(TypeCacheEntry *typcache)
Definition: rangetypes.c:2073
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define MultirangeIsEmpty(mr)

◆ multirange_intersect_internal()

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

Definition at line 1253 of file multirangetypes.c.

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

1256 {
1257  RangeType *r1;
1258  RangeType *r2;
1259  RangeType **ranges3;
1260  int32 range_count3;
1261  int32 i1;
1262  int32 i2;
1263 
1264  if (range_count1 == 0 || range_count2 == 0)
1265  return make_multirange(mltrngtypoid, rangetyp, 0, NULL);
1266 
1267  /*-----------------------------------------------
1268  * Worst case is a stitching pattern like this:
1269  *
1270  * mr1: --- --- --- ---
1271  * mr2: --- --- ---
1272  * mr3: - - - - - -
1273  *
1274  * That seems to be range_count1 + range_count2 - 1,
1275  * but one extra won't hurt.
1276  *-----------------------------------------------
1277  */
1278  ranges3 = palloc0((range_count1 + range_count2) * sizeof(RangeType *));
1279  range_count3 = 0;
1280 
1281  /*
1282  * For each range in mr1, keep intersecting until the ranges in mr2 have
1283  * passed it. The parallel progress through mr1 and mr2 is similar to
1284  * multirange_minus_multirange_internal, but we don't have to assign back
1285  * to r1.
1286  */
1287  r2 = ranges2[0];
1288  for (i1 = 0, i2 = 0; i1 < range_count1; i1++)
1289  {
1290  r1 = ranges1[i1];
1291 
1292  /* Discard r2s while r2 << r1 */
1293  while (r2 != NULL && range_before_internal(rangetyp, r2, r1))
1294  {
1295  r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1296  }
1297 
1298  while (r2 != NULL)
1299  {
1300  if (range_overlaps_internal(rangetyp, r1, r2))
1301  {
1302  /* Keep the overlapping part */
1303  ranges3[range_count3++] = range_intersect_internal(rangetyp, r1, r2);
1304 
1305  /* If we "used up" all of r2, go to the next one... */
1306  if (range_overleft_internal(rangetyp, r2, r1))
1307  r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1308 
1309  /* ...otherwise go to the next r1 */
1310  else
1311  break;
1312  }
1313  else
1314  /* We're past r1, so move to the next one */
1315  break;
1316  }
1317 
1318  /* If we're out of r2s, there can be no more intersections */
1319  if (r2 == NULL)
1320  break;
1321  }
1322 
1323  return make_multirange(mltrngtypoid, rangetyp, range_count3, ranges3);
1324 }
bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:823
signed int int32
Definition: c.h:429
void * palloc0(Size size)
Definition: mcxt.c:1093
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
bool range_overleft_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:869
RangeType * range_intersect_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:1125
bool range_before_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:646

◆ multirange_minus_internal()

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

Definition at line 1135 of file multirangetypes.c.

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

Referenced by multirange_minus().

1138 {
1139  RangeType *r1;
1140  RangeType *r2;
1141  RangeType **ranges3;
1142  int32 range_count3;
1143  int32 i1;
1144  int32 i2;
1145 
1146  /*
1147  * Worst case: every range in ranges1 makes a different cut to some range
1148  * in ranges2.
1149  */
1150  ranges3 = palloc0((range_count1 + range_count2) * sizeof(RangeType *));
1151  range_count3 = 0;
1152 
1153  /*
1154  * For each range in mr1, keep subtracting until it's gone or the ranges
1155  * in mr2 have passed it. After a subtraction we assign what's left back
1156  * to r1. The parallel progress through mr1 and mr2 is similar to
1157  * multirange_overlaps_multirange_internal.
1158  */
1159  r2 = ranges2[0];
1160  for (i1 = 0, i2 = 0; i1 < range_count1; i1++)
1161  {
1162  r1 = ranges1[i1];
1163 
1164  /* Discard r2s while r2 << r1 */
1165  while (r2 != NULL && range_before_internal(rangetyp, r2, r1))
1166  {
1167  r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1168  }
1169 
1170  while (r2 != NULL)
1171  {
1172  if (range_split_internal(rangetyp, r1, r2, &ranges3[range_count3], &r1))
1173  {
1174  /*
1175  * If r2 takes a bite out of the middle of r1, we need two
1176  * outputs
1177  */
1178  range_count3++;
1179  r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1180 
1181  }
1182  else if (range_overlaps_internal(rangetyp, r1, r2))
1183  {
1184  /*
1185  * If r2 overlaps r1, replace r1 with r1 - r2.
1186  */
1187  r1 = range_minus_internal(rangetyp, r1, r2);
1188 
1189  /*
1190  * If r2 goes past r1, then we need to stay with it, in case
1191  * it hits future r1s. Otherwise we need to keep r1, in case
1192  * future r2s hit it. Since we already subtracted, there's no
1193  * point in using the overright/overleft calls.
1194  */
1195  if (RangeIsEmpty(r1) || range_before_internal(rangetyp, r1, r2))
1196  break;
1197  else
1198  r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1199 
1200  }
1201  else
1202  {
1203  /*
1204  * This and all future r2s are past r1, so keep them. Also
1205  * assign whatever is left of r1 to the result.
1206  */
1207  break;
1208  }
1209  }
1210 
1211  /*
1212  * Nothing else can remove anything from r1, so keep it. Even if r1 is
1213  * empty here, make_multirange will remove it.
1214  */
1215  ranges3[range_count3++] = r1;
1216  }
1217 
1218  return make_multirange(mltrngtypoid, rangetyp, range_count3, ranges3);
1219 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
RangeType * range_minus_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:975
bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:823
signed int int32
Definition: c.h:429
void * palloc0(Size size)
Definition: mcxt.c:1093
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
bool range_before_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:646
bool range_split_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2, RangeType **output1, RangeType **output2)
Definition: rangetypes.c:1164

◆ multirange_ne_internal()

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

Definition at line 1849 of file multirangetypes.c.

References multirange_eq_internal().

Referenced by multirange_ne().

1852 {
1853  return (!multirange_eq_internal(rangetyp, mr1, mr2));
1854 }
bool multirange_eq_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)

◆ multirange_overlaps_multirange_internal()

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

Definition at line 1950 of file multirangetypes.c.

References multirange_get_bounds(), MultirangeIsEmpty, range_bounds_overlaps(), range_cmp_bounds(), and MultirangeType::rangeCount.

Referenced by multirange_overlaps_multirange().

1953 {
1954  int32 range_count1;
1955  int32 range_count2;
1956  int32 i1;
1957  int32 i2;
1958  RangeBound lower1,
1959  upper1,
1960  lower2,
1961  upper2;
1962 
1963  /*
1964  * Empties never overlap, even with empties. (This seems strange since
1965  * they *do* contain each other, but we want to follow how ranges work.)
1966  */
1967  if (MultirangeIsEmpty(mr1) || MultirangeIsEmpty(mr2))
1968  return false;
1969 
1970  range_count1 = mr1->rangeCount;
1971  range_count2 = mr2->rangeCount;
1972 
1973  /*
1974  * Every range in mr1 gets a chance to overlap with the ranges in mr2, but
1975  * we can use their ordering to avoid O(n^2). This is similar to
1976  * range_overlaps_multirange where r1 : r2 :: mrr : r, but there if we
1977  * don't find an overlap with r we're done, and here if we don't find an
1978  * overlap with r2 we try the next r2.
1979  */
1980  i1 = 0;
1981  multirange_get_bounds(rangetyp, mr1, i1, &lower1, &upper1);
1982  for (i1 = 0, i2 = 0; i2 < range_count2; i2++)
1983  {
1984  multirange_get_bounds(rangetyp, mr2, i2, &lower2, &upper2);
1985 
1986  /* Discard r1s while r1 << r2 */
1987  while (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0)
1988  {
1989  if (++i1 >= range_count1)
1990  return false;
1991  multirange_get_bounds(rangetyp, mr1, i1, &lower1, &upper1);
1992  }
1993 
1994  /*
1995  * If r1 && r2, we're done, otherwise we failed to find an overlap for
1996  * r2, so go to the next one.
1997  */
1998  if (range_bounds_overlaps(rangetyp, &lower1, &upper1, &lower2, &upper2))
1999  return true;
2000  }
2001 
2002  /* We looked through all of mr2 without finding an overlap */
2003  return false;
2004 }
signed int int32
Definition: c.h:429
static bool range_bounds_overlaps(TypeCacheEntry *typcache, RangeBound *lower1, RangeBound *upper1, RangeBound *lower2, RangeBound *upper2)
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)
Definition: rangetypes.c:1924

◆ range_adjacent_multirange_internal()

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

Definition at line 2406 of file multirangetypes.c.

References Assert, bounds_adjacent(), multirange_get_bounds(), MultirangeIsEmpty, range_deserialize(), MultirangeType::rangeCount, and RangeIsEmpty.

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

2409 {
2410  RangeBound lower1,
2411  upper1,
2412  lower2,
2413  upper2;
2414  bool empty;
2415  int32 range_count;
2416 
2417  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
2418  return false;
2419 
2420  range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2421  Assert(!empty);
2422 
2423  range_count = mr->rangeCount;
2424  multirange_get_bounds(rangetyp, mr, 0,
2425  &lower2, &upper2);
2426 
2427  if (bounds_adjacent(rangetyp, upper1, lower2))
2428  return true;
2429 
2430  if (range_count > 1)
2431  multirange_get_bounds(rangetyp, mr, range_count - 1,
2432  &lower2, &upper2);
2433 
2434  if (bounds_adjacent(rangetyp, upper2, lower1))
2435  return true;
2436 
2437  return false;
2438 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound boundA, RangeBound boundB)
Definition: rangetypes.c:739
signed int int32
Definition: c.h:429
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define Assert(condition)
Definition: c.h:804
#define MultirangeIsEmpty(mr)
static Ranges * range_deserialize(int maxvalues, SerializedRanges *range)

◆ range_after_multirange_internal()

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

Definition at line 2381 of file multirangetypes.c.

References Assert, multirange_get_bounds(), MultirangeIsEmpty, range_cmp_bounds(), range_deserialize(), MultirangeType::rangeCount, and RangeIsEmpty.

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

2384 {
2385  RangeBound lower1,
2386  upper1,
2387  lower2,
2388  upper2;
2389  bool empty;
2390  int32 range_count;
2391 
2392  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
2393  return false;
2394 
2395  range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2396  Assert(!empty);
2397 
2398  range_count = mr->rangeCount;
2399  multirange_get_bounds(rangetyp, mr, range_count - 1,
2400  &lower2, &upper2);
2401 
2402  return (range_cmp_bounds(rangetyp, &lower1, &upper2) > 0);
2403 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
signed int int32
Definition: c.h:429
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define Assert(condition)
Definition: c.h:804
#define MultirangeIsEmpty(mr)
static Ranges * range_deserialize(int maxvalues, SerializedRanges *range)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_before_multirange_internal()

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

Definition at line 2337 of file multirangetypes.c.

References Assert, 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().

2340 {
2341  RangeBound lower1,
2342  upper1,
2343  lower2,
2344  upper2;
2345  bool empty;
2346 
2347  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
2348  return false;
2349 
2350  range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2351  Assert(!empty);
2352 
2353  multirange_get_bounds(rangetyp, mr, 0, &lower2, &upper2);
2354 
2355  return (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0);
2356 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define Assert(condition)
Definition: c.h:804
#define MultirangeIsEmpty(mr)
static Ranges * range_deserialize(int maxvalues, SerializedRanges *range)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_contains_multirange_internal()

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

Definition at line 1764 of file multirangetypes.c.

References Assert, multirange_get_bounds(), MultirangeIsEmpty, range_bounds_contains(), range_deserialize(), MultirangeType::rangeCount, and RangeIsEmpty.

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

1767 {
1768  RangeBound lower1,
1769  upper1,
1770  lower2,
1771  upper2,
1772  tmp;
1773  bool empty;
1774 
1775  /*
1776  * Every range contains an infinite number of empty multiranges, even an
1777  * empty one.
1778  */
1779  if (MultirangeIsEmpty(mr))
1780  return true;
1781 
1782  if (RangeIsEmpty(r))
1783  return false;
1784 
1785  /* Range contains multirange iff it contains its union range. */
1786  range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
1787  Assert(!empty);
1788  multirange_get_bounds(rangetyp, mr, 0, &lower2, &tmp);
1789  multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1, &tmp, &upper2);
1790 
1791  return range_bounds_contains(rangetyp, &lower1, &upper1, &lower2, &upper2);
1792 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define Assert(condition)
Definition: c.h:804
#define MultirangeIsEmpty(mr)
static Ranges * range_deserialize(int maxvalues, SerializedRanges *range)
static bool range_bounds_contains(TypeCacheEntry *typcache, RangeBound *lower1, RangeBound *upper1, RangeBound *lower2, RangeBound *upper2)

◆ range_overlaps_multirange_internal()

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

Definition at line 1928 of file multirangetypes.c.

References Assert, 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().

1931 {
1932  RangeBound bounds[2];
1933  bool empty;
1934 
1935  /*
1936  * Empties never overlap, even with empties. (This seems strange since
1937  * they *do* contain each other, but we want to follow how ranges work.)
1938  */
1939  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
1940  return false;
1941 
1942  range_deserialize(rangetyp, r, &bounds[0], &bounds[1], &empty);
1943  Assert(!empty);
1944 
1945  return multirange_bsearch_match(rangetyp, mr, bounds,
1947 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
static bool multirange_bsearch_match(TypeCacheEntry *typcache, const MultirangeType *mr, void *key, multirange_bsearch_comparison cmp_func)
#define Assert(condition)
Definition: c.h:804
#define MultirangeIsEmpty(mr)
static Ranges * range_deserialize(int maxvalues, SerializedRanges *range)
static int multirange_range_overlaps_bsearch_comparison(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)

◆ range_overleft_multirange_internal()

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

Definition at line 2008 of file multirangetypes.c.

References Assert, multirange_get_bounds(), MultirangeIsEmpty, PG_RETURN_BOOL, range_cmp_bounds(), range_deserialize(), MultirangeType::rangeCount, and RangeIsEmpty.

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

2011 {
2012  RangeBound lower1,
2013  upper1,
2014  lower2,
2015  upper2;
2016  bool empty;
2017 
2018  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
2019  PG_RETURN_BOOL(false);
2020 
2021 
2022  range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2023  Assert(!empty);
2024  multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1,
2025  &lower2, &upper2);
2026 
2027  PG_RETURN_BOOL(range_cmp_bounds(rangetyp, &upper1, &upper2) <= 0);
2028 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define Assert(condition)
Definition: c.h:804
#define MultirangeIsEmpty(mr)
static Ranges * range_deserialize(int maxvalues, SerializedRanges *range)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_overright_multirange_internal()

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

Definition at line 2093 of file multirangetypes.c.

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

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

2096 {
2097  RangeBound lower1,
2098  upper1,
2099  lower2,
2100  upper2;
2101  bool empty;
2102 
2103  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
2104  PG_RETURN_BOOL(false);
2105 
2106  range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2107  Assert(!empty);
2108  multirange_get_bounds(rangetyp, mr, 0, &lower2, &upper2);
2109 
2110  return (range_cmp_bounds(rangetyp, &lower1, &lower2) >= 0);
2111 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define Assert(condition)
Definition: c.h:804
#define MultirangeIsEmpty(mr)
static Ranges * range_deserialize(int maxvalues, SerializedRanges *range)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924