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

References make_multirange().

Referenced by multirange_intersect().

836 {
837  return make_multirange(mltrngtypoid, rangetyp, 0, NULL);
838 }
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 636 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().

638 {
639  MultirangeType *multirange;
640  Size size;
641 
642  /* Sort and merge input ranges. */
643  range_count = multirange_canonicalize(rangetyp, range_count, ranges);
644 
645  /* Note: zero-fill is required here, just as in heap tuples */
646  size = multirange_size_estimate(rangetyp, range_count, ranges);
647  multirange = palloc0(size);
648  SET_VARSIZE(multirange, size);
649 
650  /* Now fill in the datum */
651  multirange->multirangetypid = mltrngtypoid;
652  multirange->rangeCount = range_count;
653 
654  write_multirange_data(multirange, rangetyp, range_count, ranges);
655 
656  return multirange;
657 }
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 2361 of file multirangetypes.c.

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

Referenced by multirange_after_multirange(), and multirange_before_multirange().

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

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

Referenced by elem_contained_by_multirange(), and multirange_contains_elem().

1646 {
1647  if (MultirangeIsEmpty(mr))
1648  return false;
1649 
1650  return multirange_bsearch_match(rangetyp, mr, &val,
1652 }
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 2203 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().

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

1741 {
1742  RangeBound bounds[2];
1743  bool empty;
1744 
1745  /*
1746  * Every multirange contains an infinite number of empty ranges, even an
1747  * empty one.
1748  */
1749  if (RangeIsEmpty(r))
1750  return true;
1751 
1752  if (MultirangeIsEmpty(mr))
1753  return false;
1754 
1755  range_deserialize(rangetyp, r, &bounds[0], &bounds[1], &empty);
1756  Assert(!empty);
1757 
1758  return multirange_bsearch_match(rangetyp, mr, bounds,
1760 }
#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 813 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().

816 {
817  *range_count = multirange->rangeCount;
818 
819  /* Convert each ShortRangeType into a RangeType */
820  if (*range_count > 0)
821  {
822  int i;
823 
824  *ranges = palloc(*range_count * sizeof(RangeType *));
825  for (i = 0; i < *range_count; i++)
826  (*ranges)[i] = multirange_get_range(rangetyp, multirange, i);
827  }
828  else
829  {
830  *ranges = NULL;
831  }
832 }
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 1801 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().

1804 {
1805  int32 range_count_1;
1806  int32 range_count_2;
1807  int32 i;
1808  RangeBound lower1,
1809  upper1,
1810  lower2,
1811  upper2;
1812 
1813  /* Different types should be prevented by ANYMULTIRANGE matching rules */
1814  if (MultirangeTypeGetOid(mr1) != MultirangeTypeGetOid(mr2))
1815  elog(ERROR, "multirange types do not match");
1816 
1817  range_count_1 = mr1->rangeCount;
1818  range_count_2 = mr2->rangeCount;
1819 
1820  if (range_count_1 != range_count_2)
1821  return false;
1822 
1823  for (i = 0; i < range_count_1; i++)
1824  {
1825  multirange_get_bounds(rangetyp, mr1, i, &lower1, &upper1);
1826  multirange_get_bounds(rangetyp, mr2, i, &lower2, &upper2);
1827 
1828  if (range_cmp_bounds(rangetyp, &lower1, &lower2) != 0 ||
1829  range_cmp_bounds(rangetyp, &upper1, &upper2) != 0)
1830  return false;
1831  }
1832 
1833  return true;
1834 }
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 731 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().

734 {
735  uint32 offset;
736  uint8 flags;
737  Pointer ptr;
738  int16 typlen = rangetyp->rngelemtype->typlen;
739  char typalign = rangetyp->rngelemtype->typalign;
740  bool typbyval = rangetyp->rngelemtype->typbyval;
741  Datum lbound;
742  Datum ubound;
743 
744  Assert(i < multirange->rangeCount);
745 
746  offset = multirange_get_bounds_offset(multirange, i);
747  flags = MultirangeGetFlagsPtr(multirange)[i];
748  ptr = MultirangeGetBoundariesPtr(multirange, typalign) + offset;
749 
750  /* multirange can't contain empty ranges */
751  Assert((flags & RANGE_EMPTY) == 0);
752 
753  /* fetch lower bound, if any */
754  if (RANGE_HAS_LBOUND(flags))
755  {
756  /* att_align_pointer cannot be necessary here */
757  lbound = fetch_att(ptr, typbyval, typlen);
758  ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr);
759  }
760  else
761  lbound = (Datum) 0;
762 
763  /* fetch upper bound, if any */
764  if (RANGE_HAS_UBOUND(flags))
765  {
766  ptr = (Pointer) att_align_pointer(ptr, typalign, typlen, ptr);
767  ubound = fetch_att(ptr, typbyval, typlen);
768  /* no need for att_addlength_pointer */
769  }
770  else
771  ubound = (Datum) 0;
772 
773  /* emit results */
774  lower->val = lbound;
775  lower->infinite = (flags & RANGE_LB_INF) != 0;
776  lower->inclusive = (flags & RANGE_LB_INC) != 0;
777  lower->lower = true;
778 
779  upper->val = ubound;
780  upper->infinite = (flags & RANGE_UB_INF) != 0;
781  upper->inclusive = (flags & RANGE_UB_INC) != 0;
782  upper->lower = false;
783 }
#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 685 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(), and range_merge_from_multirange().

687 {
688  uint32 offset;
689  uint8 flags;
690  Pointer begin,
691  ptr;
692  int16 typlen = rangetyp->rngelemtype->typlen;
693  char typalign = rangetyp->rngelemtype->typalign;
694  uint32 len;
695  RangeType *range;
696 
697  Assert(i < multirange->rangeCount);
698 
699  offset = multirange_get_bounds_offset(multirange, i);
700  flags = MultirangeGetFlagsPtr(multirange)[i];
701  ptr = begin = MultirangeGetBoundariesPtr(multirange, typalign) + offset;
702 
703  /*
704  * Calculate the size of bound values. In principle, we could get offset
705  * of the next range bound values and calculate accordingly. But range
706  * bound values are aligned, so we have to walk the values to get the
707  * exact size.
708  */
709  if (RANGE_HAS_LBOUND(flags))
710  ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr);
711  if (RANGE_HAS_UBOUND(flags))
712  ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr);
713  len = (ptr - begin) + sizeof(RangeType) + sizeof(uint8);
714 
715  range = palloc0(len);
716  SET_VARSIZE(range, len);
717  range->rangetypid = rangetyp->type_id;
718 
719  memcpy(range + 1, begin, ptr - begin);
720  *((uint8 *) (range + 1) + (ptr - begin)) = flags;
721 
722  return range;
723 }
#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 538 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().

539 {
540  TypeCacheEntry *typcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
541 
542  if (typcache == NULL ||
543  typcache->type_id != mltrngtypid)
544  {
545  typcache = lookup_type_cache(mltrngtypid, TYPECACHE_MULTIRANGE_INFO);
546  if (typcache->rngtype == NULL)
547  elog(ERROR, "type %u is not a multirange type", mltrngtypid);
548  fcinfo->flinfo->fn_extra = (void *) typcache;
549  }
550 
551  return typcache;
552 }
#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:338
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 789 of file multirangetypes.c.

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

Referenced by multirange_gist_compress().

791 {
793  upper,
794  tmp;
795 
796  if (MultirangeIsEmpty(mr))
797  return make_empty_range(rangetyp);
798 
799  multirange_get_bounds(rangetyp, mr, 0, &lower, &tmp);
800  multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1, &tmp, &upper);
801 
802  return make_range(rangetyp, &lower, &upper, false);
803 }
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 1255 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().

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

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

References multirange_eq_internal().

Referenced by multirange_ne().

1854 {
1855  return (!multirange_eq_internal(rangetyp, mr1, mr2));
1856 }
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 1952 of file multirangetypes.c.

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

Referenced by multirange_overlaps_multirange().

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

2411 {
2412  RangeBound lower1,
2413  upper1,
2414  lower2,
2415  upper2;
2416  bool empty;
2417  int32 range_count;
2418 
2419  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
2420  return false;
2421 
2422  range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2423  Assert(!empty);
2424 
2425  range_count = mr->rangeCount;
2426  multirange_get_bounds(rangetyp, mr, 0,
2427  &lower2, &upper2);
2428 
2429  if (bounds_adjacent(rangetyp, upper1, lower2))
2430  return true;
2431 
2432  if (range_count > 1)
2433  multirange_get_bounds(rangetyp, mr, range_count - 1,
2434  &lower2, &upper2);
2435 
2436  if (bounds_adjacent(rangetyp, upper2, lower1))
2437  return true;
2438 
2439  return false;
2440 }
#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 2383 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().

2386 {
2387  RangeBound lower1,
2388  upper1,
2389  lower2,
2390  upper2;
2391  bool empty;
2392  int32 range_count;
2393 
2394  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
2395  return false;
2396 
2397  range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2398  Assert(!empty);
2399 
2400  range_count = mr->rangeCount;
2401  multirange_get_bounds(rangetyp, mr, range_count - 1,
2402  &lower2, &upper2);
2403 
2404  return (range_cmp_bounds(rangetyp, &lower1, &upper2) > 0);
2405 }
#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 2339 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().

2342 {
2343  RangeBound lower1,
2344  upper1,
2345  lower2,
2346  upper2;
2347  bool empty;
2348 
2349  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
2350  return false;
2351 
2352  range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2353  Assert(!empty);
2354 
2355  multirange_get_bounds(rangetyp, mr, 0, &lower2, &upper2);
2356 
2357  return (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0);
2358 }
#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 1766 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().

1769 {
1770  RangeBound lower1,
1771  upper1,
1772  lower2,
1773  upper2,
1774  tmp;
1775  bool empty;
1776 
1777  /*
1778  * Every range contains an infinite number of empty multiranges, even an
1779  * empty one.
1780  */
1781  if (MultirangeIsEmpty(mr))
1782  return true;
1783 
1784  if (RangeIsEmpty(r))
1785  return false;
1786 
1787  /* Range contains multirange iff it contains its union range. */
1788  range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
1789  Assert(!empty);
1790  multirange_get_bounds(rangetyp, mr, 0, &lower2, &tmp);
1791  multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1, &tmp, &upper2);
1792 
1793  return range_bounds_contains(rangetyp, &lower1, &upper1, &lower2, &upper2);
1794 }
#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 1930 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().

1933 {
1934  RangeBound bounds[2];
1935  bool empty;
1936 
1937  /*
1938  * Empties never overlap, even with empties. (This seems strange since
1939  * they *do* contain each other, but we want to follow how ranges work.)
1940  */
1941  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
1942  return false;
1943 
1944  range_deserialize(rangetyp, r, &bounds[0], &bounds[1], &empty);
1945  Assert(!empty);
1946 
1947  return multirange_bsearch_match(rangetyp, mr, bounds,
1949 }
#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 2010 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().

2013 {
2014  RangeBound lower1,
2015  upper1,
2016  lower2,
2017  upper2;
2018  bool empty;
2019 
2020  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
2021  PG_RETURN_BOOL(false);
2022 
2023 
2024  range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2025  Assert(!empty);
2026  multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1,
2027  &lower2, &upper2);
2028 
2029  PG_RETURN_BOOL(range_cmp_bounds(rangetyp, &upper1, &upper2) <= 0);
2030 }
#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 2095 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().

2098 {
2099  RangeBound lower1,
2100  upper1,
2101  lower2,
2102  upper2;
2103  bool empty;
2104 
2105  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
2106  PG_RETURN_BOOL(false);
2107 
2108  range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2109  Assert(!empty);
2110  multirange_get_bounds(rangetyp, mr, 0, &lower2, &upper2);
2111 
2112  return (range_cmp_bounds(rangetyp, &lower1, &lower2) >= 0);
2113 }
#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