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

Go to the source code of this file.

Data Structures

struct  RangeType
 
struct  RangeBound
 

Macros

#define RANGE_EMPTY_LITERAL   "empty"
 
#define RangeTypeGetOid(r)   ((r)->rangetypid)
 
#define RANGE_EMPTY   0x01 /* range is empty */
 
#define RANGE_LB_INC   0x02 /* lower bound is inclusive */
 
#define RANGE_UB_INC   0x04 /* upper bound is inclusive */
 
#define RANGE_LB_INF   0x08 /* lower bound is -infinity */
 
#define RANGE_UB_INF   0x10 /* upper bound is +infinity */
 
#define RANGE_LB_NULL   0x20 /* lower bound is null (NOT USED) */
 
#define RANGE_UB_NULL   0x40 /* upper bound is null (NOT USED) */
 
#define RANGE_CONTAIN_EMPTY
 
#define RANGE_HAS_LBOUND(flags)
 
#define RANGE_HAS_UBOUND(flags)
 
#define RangeIsEmpty(r)   ((range_get_flags(r) & RANGE_EMPTY) != 0)
 
#define RangeIsOrContainsEmpty(r)   ((range_get_flags(r) & (RANGE_EMPTY | RANGE_CONTAIN_EMPTY)) != 0)
 
#define DatumGetRangeTypeP(X)   ((RangeType *) PG_DETOAST_DATUM(X))
 
#define DatumGetRangeTypePCopy(X)   ((RangeType *) PG_DETOAST_DATUM_COPY(X))
 
#define RangeTypePGetDatum(X)   PointerGetDatum(X)
 
#define PG_GETARG_RANGE_P(n)   DatumGetRangeTypeP(PG_GETARG_DATUM(n))
 
#define PG_GETARG_RANGE_P_COPY(n)   DatumGetRangeTypePCopy(PG_GETARG_DATUM(n))
 
#define PG_RETURN_RANGE_P(x)   return RangeTypePGetDatum(x)
 
#define RANGESTRAT_BEFORE   RTLeftStrategyNumber
 
#define RANGESTRAT_OVERLEFT   RTOverLeftStrategyNumber
 
#define RANGESTRAT_OVERLAPS   RTOverlapStrategyNumber
 
#define RANGESTRAT_OVERRIGHT   RTOverRightStrategyNumber
 
#define RANGESTRAT_AFTER   RTRightStrategyNumber
 
#define RANGESTRAT_ADJACENT   RTSameStrategyNumber
 
#define RANGESTRAT_CONTAINS   RTContainsStrategyNumber
 
#define RANGESTRAT_CONTAINED_BY   RTContainedByStrategyNumber
 
#define RANGESTRAT_CONTAINS_ELEM   RTContainsElemStrategyNumber
 
#define RANGESTRAT_EQ   RTEqualStrategyNumber
 

Functions

bool range_contains_elem_internal (TypeCacheEntry *typcache, const RangeType *r, Datum val)
 
bool range_eq_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
bool range_ne_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
bool range_contains_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
bool range_contained_by_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
bool range_before_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
bool range_after_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
bool range_adjacent_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
bool range_overlaps_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
bool range_overleft_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
bool range_overright_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
RangeTyperange_union_internal (TypeCacheEntry *typcache, RangeType *r1, RangeType *r2, bool strict)
 
RangeTyperange_minus_internal (TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
 
RangeTyperange_intersect_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
TypeCacheEntryrange_get_typcache (FunctionCallInfo fcinfo, Oid rngtypid)
 
RangeTyperange_serialize (TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
 
void range_deserialize (TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
 
char range_get_flags (const RangeType *range)
 
void range_set_contain_empty (RangeType *range)
 
RangeTypemake_range (TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
 
int range_cmp_bounds (TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
 
int range_cmp_bound_values (TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
 
int range_compare (const void *key1, const void *key2, void *arg)
 
bool bounds_adjacent (TypeCacheEntry *typcache, RangeBound bound1, RangeBound bound2)
 
RangeTypemake_empty_range (TypeCacheEntry *typcache)
 
bool range_split_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2, RangeType **output1, RangeType **output2)
 

Macro Definition Documentation

◆ DatumGetRangeTypeP

◆ DatumGetRangeTypePCopy

#define DatumGetRangeTypePCopy (   X)    ((RangeType *) PG_DETOAST_DATUM_COPY(X))

Definition at line 74 of file rangetypes.h.

◆ PG_GETARG_RANGE_P

◆ PG_GETARG_RANGE_P_COPY

#define PG_GETARG_RANGE_P_COPY (   n)    DatumGetRangeTypePCopy(PG_GETARG_DATUM(n))

Definition at line 77 of file rangetypes.h.

◆ PG_RETURN_RANGE_P

◆ RANGE_CONTAIN_EMPTY

#define RANGE_CONTAIN_EMPTY
Value:
0x80 /* marks a GiST internal-page entry whose
* subtree contains some empty ranges */

Definition at line 45 of file rangetypes.h.

Referenced by get_gist_range_class(), range_set_contain_empty(), and range_super_union().

◆ RANGE_EMPTY

#define RANGE_EMPTY   0x01 /* range is empty */

◆ RANGE_EMPTY_LITERAL

#define RANGE_EMPTY_LITERAL   "empty"

Definition at line 32 of file rangetypes.h.

Referenced by multirange_in(), range_deparse(), and range_parse().

◆ RANGE_HAS_LBOUND

#define RANGE_HAS_LBOUND (   flags)

◆ RANGE_HAS_UBOUND

#define RANGE_HAS_UBOUND (   flags)

◆ RANGE_LB_INC

#define RANGE_LB_INC   0x02 /* lower bound is inclusive */

◆ RANGE_LB_INF

#define RANGE_LB_INF   0x08 /* lower bound is -infinity */

◆ RANGE_LB_NULL

#define RANGE_LB_NULL   0x20 /* lower bound is null (NOT USED) */

Definition at line 43 of file rangetypes.h.

◆ RANGE_UB_INC

#define RANGE_UB_INC   0x04 /* upper bound is inclusive */

◆ RANGE_UB_INF

#define RANGE_UB_INF   0x10 /* upper bound is +infinity */

◆ RANGE_UB_NULL

#define RANGE_UB_NULL   0x40 /* upper bound is null (NOT USED) */

Definition at line 44 of file rangetypes.h.

◆ RangeIsEmpty

◆ RangeIsOrContainsEmpty

#define RangeIsOrContainsEmpty (   r)    ((range_get_flags(r) & (RANGE_EMPTY | RANGE_CONTAIN_EMPTY)) != 0)

◆ RANGESTRAT_ADJACENT

◆ RANGESTRAT_AFTER

◆ RANGESTRAT_BEFORE

◆ RANGESTRAT_CONTAINED_BY

◆ RANGESTRAT_CONTAINS

◆ RANGESTRAT_CONTAINS_ELEM

◆ RANGESTRAT_EQ

◆ RANGESTRAT_OVERLAPS

◆ RANGESTRAT_OVERLEFT

◆ RANGESTRAT_OVERRIGHT

◆ RangeTypeGetOid

◆ RangeTypePGetDatum

Function Documentation

◆ bounds_adjacent()

bool bounds_adjacent ( TypeCacheEntry typcache,
RangeBound  bound1,
RangeBound  bound2 
)

Definition at line 739 of file rangetypes.c.

References Assert, cmp(), FmgrInfo::fn_oid, RangeBound::inclusive, RangeBound::lower, make_range(), OidIsValid, range_cmp_bound_values(), RangeIsEmpty, and TypeCacheEntry::rng_canonical_finfo.

Referenced by adjacent_cmp_bounds(), multirange_adjacent_multirange(), range_adjacent_internal(), and range_adjacent_multirange_internal().

740 {
741  int cmp;
742 
743  Assert(!boundA.lower && boundB.lower);
744 
745  cmp = range_cmp_bound_values(typcache, &boundA, &boundB);
746  if (cmp < 0)
747  {
748  RangeType *r;
749 
750  /*
751  * Bounds do not overlap; see if there are points in between.
752  */
753 
754  /* in a continuous subtype, there are assumed to be points between */
755  if (!OidIsValid(typcache->rng_canonical_finfo.fn_oid))
756  return false;
757 
758  /*
759  * The bounds are of a discrete range type; so make a range A..B and
760  * see if it's empty.
761  */
762 
763  /* flip the inclusion flags */
764  boundA.inclusive = !boundA.inclusive;
765  boundB.inclusive = !boundB.inclusive;
766  /* change upper/lower labels to avoid Assert failures */
767  boundA.lower = true;
768  boundB.lower = false;
769  r = make_range(typcache, &boundA, &boundB, false);
770  return RangeIsEmpty(r);
771  }
772  else if (cmp == 0)
773  return boundA.inclusive != boundB.inclusive;
774  else
775  return false; /* bounds overlap */
776 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1884
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
int range_cmp_bound_values(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1998
#define OidIsValid(objectId)
Definition: c.h:710
FmgrInfo rng_canonical_finfo
Definition: typcache.h:101
Oid fn_oid
Definition: fmgr.h:59
#define Assert(condition)
Definition: c.h:804
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ make_empty_range()

RangeType* make_empty_range ( TypeCacheEntry typcache)

Definition at line 2073 of file rangetypes.c.

References RangeBound::inclusive, RangeBound::infinite, lower(), RangeBound::lower, make_range(), upper(), and RangeBound::val.

Referenced by multirange_get_union_range(), range_intersect_internal(), range_merge_from_multirange(), and range_minus_internal().

2074 {
2075  RangeBound lower;
2076  RangeBound upper;
2077 
2078  lower.val = (Datum) 0;
2079  lower.infinite = false;
2080  lower.inclusive = false;
2081  lower.lower = true;
2082 
2083  upper.val = (Datum) 0;
2084  upper.infinite = false;
2085  upper.inclusive = false;
2086  upper.lower = false;
2087 
2088  return make_range(typcache, &lower, &upper, true);
2089 }
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
Datum val
Definition: rangetypes.h:64
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
bool inclusive
Definition: rangetypes.h:66
bool lower
Definition: rangetypes.h:67
uintptr_t Datum
Definition: postgres.h:411
bool infinite
Definition: rangetypes.h:65

◆ make_range()

RangeType* make_range ( TypeCacheEntry typcache,
RangeBound lower,
RangeBound upper,
bool  empty 
)

Definition at line 1884 of file rangetypes.c.

References DatumGetRangeTypeP, FmgrInfo::fn_oid, FunctionCall1, OidIsValid, range(), range_serialize(), RangeIsEmpty, RangeTypePGetDatum, and TypeCacheEntry::rng_canonical_finfo.

Referenced by bounds_adjacent(), make_empty_range(), multirange_get_union_range(), range_constructor2(), range_constructor3(), range_in(), range_intersect_internal(), range_merge_from_multirange(), range_minus_internal(), range_recv(), range_split_internal(), range_super_union(), and range_union_internal().

1886 {
1887  RangeType *range;
1888 
1889  range = range_serialize(typcache, lower, upper, empty);
1890 
1891  /* no need to call canonical on empty ranges ... */
1892  if (OidIsValid(typcache->rng_canonical_finfo.fn_oid) &&
1893  !RangeIsEmpty(range))
1895  RangeTypePGetDatum(range)));
1896 
1897  return range;
1898 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
#define OidIsValid(objectId)
Definition: c.h:710
#define RangeTypePGetDatum(X)
Definition: rangetypes.h:75
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1659
FmgrInfo rng_canonical_finfo
Definition: typcache.h:101
Oid fn_oid
Definition: fmgr.h:59
#define DatumGetRangeTypeP(X)
Definition: rangetypes.h:73
#define FunctionCall1(flinfo, arg1)
Definition: fmgr.h:644

◆ range_adjacent_internal()

bool range_adjacent_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 780 of file rangetypes.c.

References bounds_adjacent(), elog, ERROR, range_deserialize(), and RangeTypeGetOid.

Referenced by multirange_canonicalize(), range_adjacent(), range_gist_consistent_int_range(), range_gist_consistent_leaf_range(), range_union_internal(), and spg_range_quad_leaf_consistent().

781 {
782  RangeBound lower1,
783  lower2;
784  RangeBound upper1,
785  upper2;
786  bool empty1,
787  empty2;
788 
789  /* Different types should be prevented by ANYRANGE matching rules */
790  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
791  elog(ERROR, "range types do not match");
792 
793  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
794  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
795 
796  /* An empty range is not adjacent to any other range */
797  if (empty1 || empty2)
798  return false;
799 
800  /*
801  * Given two ranges A..B and C..D, the ranges are adjacent if and only if
802  * B is adjacent to C, or D is adjacent to A.
803  */
804  return (bounds_adjacent(typcache, upper1, lower2) ||
805  bounds_adjacent(typcache, upper2, lower1));
806 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound boundA, RangeBound boundB)
Definition: rangetypes.c:739
#define ERROR
Definition: elog.h:46
#define elog(elevel,...)
Definition: elog.h:232

◆ range_after_internal()

bool range_after_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 684 of file rangetypes.c.

References elog, ERROR, range_cmp_bounds(), range_deserialize(), and RangeTypeGetOid.

Referenced by range_after(), range_gist_consistent_int_range(), range_gist_consistent_leaf_range(), and spg_range_quad_leaf_consistent().

685 {
686  RangeBound lower1,
687  lower2;
688  RangeBound upper1,
689  upper2;
690  bool empty1,
691  empty2;
692 
693  /* Different types should be prevented by ANYRANGE matching rules */
694  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
695  elog(ERROR, "range types do not match");
696 
697  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
698  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
699 
700  /* An empty range is neither before nor after any other range */
701  if (empty1 || empty2)
702  return false;
703 
704  return (range_cmp_bounds(typcache, &lower1, &upper2) > 0);
705 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define ERROR
Definition: elog.h:46
#define elog(elevel,...)
Definition: elog.h:232
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_before_internal()

bool range_before_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 646 of file rangetypes.c.

References elog, ERROR, range_cmp_bounds(), range_deserialize(), and RangeTypeGetOid.

Referenced by multirange_canonicalize(), multirange_intersect_internal(), multirange_minus_internal(), range_before(), range_gist_consistent_int_range(), range_gist_consistent_leaf_range(), and spg_range_quad_leaf_consistent().

647 {
648  RangeBound lower1,
649  lower2;
650  RangeBound upper1,
651  upper2;
652  bool empty1,
653  empty2;
654 
655  /* Different types should be prevented by ANYRANGE matching rules */
656  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
657  elog(ERROR, "range types do not match");
658 
659  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
660  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
661 
662  /* An empty range is neither before nor after any other range */
663  if (empty1 || empty2)
664  return false;
665 
666  return (range_cmp_bounds(typcache, &upper1, &lower2) < 0);
667 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define ERROR
Definition: elog.h:46
#define elog(elevel,...)
Definition: elog.h:232
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_cmp_bound_values()

int range_cmp_bound_values ( TypeCacheEntry typcache,
const RangeBound b1,
const RangeBound b2 
)

Definition at line 1998 of file rangetypes.c.

References DatumGetInt32, FunctionCall2Coll(), RangeBound::infinite, RangeBound::lower, TypeCacheEntry::rng_cmp_proc_finfo, TypeCacheEntry::rng_collation, and RangeBound::val.

Referenced by bounds_adjacent(), and range_serialize().

2000 {
2001  /*
2002  * First, handle cases involving infinity, which don't require invoking
2003  * the comparison proc.
2004  */
2005  if (b1->infinite && b2->infinite)
2006  {
2007  /*
2008  * Both are infinity, so they are equal unless one is lower and the
2009  * other not.
2010  */
2011  if (b1->lower == b2->lower)
2012  return 0;
2013  else
2014  return b1->lower ? -1 : 1;
2015  }
2016  else if (b1->infinite)
2017  return b1->lower ? -1 : 1;
2018  else if (b2->infinite)
2019  return b2->lower ? 1 : -1;
2020 
2021  /*
2022  * Both boundaries are finite, so compare the held values.
2023  */
2025  typcache->rng_collation,
2026  b1->val, b2->val));
2027 }
FmgrInfo rng_cmp_proc_finfo
Definition: typcache.h:100
#define DatumGetInt32(X)
Definition: postgres.h:516
Datum val
Definition: rangetypes.h:64
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1148
bool lower
Definition: rangetypes.h:67
bool infinite
Definition: rangetypes.h:65
Oid rng_collation
Definition: typcache.h:99

◆ range_cmp_bounds()

int range_cmp_bounds ( TypeCacheEntry typcache,
const RangeBound b1,
const RangeBound b2 
)

Definition at line 1924 of file rangetypes.c.

References DatumGetInt32, FunctionCall2Coll(), RangeBound::inclusive, RangeBound::infinite, RangeBound::lower, TypeCacheEntry::rng_cmp_proc_finfo, TypeCacheEntry::rng_collation, and RangeBound::val.

Referenced by adjacent_cmp_bounds(), adjacent_inner_consistent(), bound_cmp(), calc_hist_selectivity_contained(), getQuadrant(), interval_cmp_lower(), interval_cmp_upper(), multirange_before_multirange_internal(), multirange_cmp(), multirange_contains_multirange_internal(), multirange_eq_internal(), multirange_overlaps_multirange_internal(), multirange_overleft_multirange(), multirange_overleft_range(), multirange_overright_multirange(), multirange_overright_range(), multirange_range_contains_bsearch_comparison(), multirange_range_overlaps_bsearch_comparison(), multirange_union_range_equal(), range_after_internal(), range_after_multirange_internal(), range_before_internal(), range_before_multirange_internal(), range_bound_qsort_cmp(), range_bounds_contains(), range_bounds_overlaps(), range_cmp(), range_compare(), range_contains_internal(), range_eq_internal(), range_gist_double_sorting_split(), range_gist_penalty(), range_intersect_internal(), range_minus_internal(), range_overlaps_internal(), range_overleft_internal(), range_overleft_multirange_internal(), range_overright_internal(), range_overright_multirange_internal(), range_split_internal(), range_super_union(), range_union_internal(), rbound_bsearch(), single_bound_cmp(), and spg_range_quad_inner_consistent().

1925 {
1926  int32 result;
1927 
1928  /*
1929  * First, handle cases involving infinity, which don't require invoking
1930  * the comparison proc.
1931  */
1932  if (b1->infinite && b2->infinite)
1933  {
1934  /*
1935  * Both are infinity, so they are equal unless one is lower and the
1936  * other not.
1937  */
1938  if (b1->lower == b2->lower)
1939  return 0;
1940  else
1941  return b1->lower ? -1 : 1;
1942  }
1943  else if (b1->infinite)
1944  return b1->lower ? -1 : 1;
1945  else if (b2->infinite)
1946  return b2->lower ? 1 : -1;
1947 
1948  /*
1949  * Both boundaries are finite, so compare the held values.
1950  */
1952  typcache->rng_collation,
1953  b1->val, b2->val));
1954 
1955  /*
1956  * If the comparison is anything other than equal, we're done. If they
1957  * compare equal though, we still have to consider whether the boundaries
1958  * are inclusive or exclusive.
1959  */
1960  if (result == 0)
1961  {
1962  if (!b1->inclusive && !b2->inclusive)
1963  {
1964  /* both are exclusive */
1965  if (b1->lower == b2->lower)
1966  return 0;
1967  else
1968  return b1->lower ? 1 : -1;
1969  }
1970  else if (!b1->inclusive)
1971  return b1->lower ? 1 : -1;
1972  else if (!b2->inclusive)
1973  return b2->lower ? -1 : 1;
1974  else
1975  {
1976  /*
1977  * Both are inclusive and the values held are equal, so they are
1978  * equal regardless of whether they are upper or lower boundaries,
1979  * or a mix.
1980  */
1981  return 0;
1982  }
1983  }
1984 
1985  return result;
1986 }
FmgrInfo rng_cmp_proc_finfo
Definition: typcache.h:100
#define DatumGetInt32(X)
Definition: postgres.h:516
Datum val
Definition: rangetypes.h:64
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1148
signed int int32
Definition: c.h:429
bool inclusive
Definition: rangetypes.h:66
bool lower
Definition: rangetypes.h:67
bool infinite
Definition: rangetypes.h:65
Oid rng_collation
Definition: typcache.h:99

◆ range_compare()

int range_compare ( const void *  key1,
const void *  key2,
void *  arg 
)

Definition at line 2037 of file rangetypes.c.

References cmp(), range_cmp_bounds(), range_deserialize(), and RangeIOData::typcache.

Referenced by multirange_canonicalize().

2038 {
2039  RangeType *r1 = *(RangeType **) key1;
2040  RangeType *r2 = *(RangeType **) key2;
2041  TypeCacheEntry *typcache = (TypeCacheEntry *) arg;
2042  RangeBound lower1;
2043  RangeBound upper1;
2044  RangeBound lower2;
2045  RangeBound upper2;
2046  bool empty1;
2047  bool empty2;
2048  int cmp;
2049 
2050  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
2051  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
2052 
2053  if (empty1 && empty2)
2054  cmp = 0;
2055  else if (empty1)
2056  cmp = -1;
2057  else if (empty2)
2058  cmp = 1;
2059  else
2060  {
2061  cmp = range_cmp_bounds(typcache, &lower1, &lower2);
2062  if (cmp == 0)
2063  cmp = range_cmp_bounds(typcache, &upper1, &upper2);
2064  }
2065 
2066  return cmp;
2067 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
void * arg
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ range_contained_by_internal()

bool range_contained_by_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 2464 of file rangetypes.c.

References range_contains_internal().

Referenced by range_contained_by(), range_gist_consistent_leaf_range(), and spg_range_quad_leaf_consistent().

2465 {
2466  return range_contains_internal(typcache, r2, r1);
2467 }
bool range_contains_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:2432

◆ range_contains_elem_internal()

bool range_contains_elem_internal ( TypeCacheEntry typcache,
const RangeType r,
Datum  val 
)

Definition at line 2473 of file rangetypes.c.

References cmp(), DatumGetInt32, FunctionCall2Coll(), RangeBound::inclusive, RangeBound::infinite, lower(), range_deserialize(), TypeCacheEntry::rng_cmp_proc_finfo, TypeCacheEntry::rng_collation, upper(), and RangeBound::val.

Referenced by elem_contained_by_range(), range_contains_elem(), range_gist_consistent_int_element(), range_gist_consistent_leaf_element(), and spg_range_quad_leaf_consistent().

2474 {
2475  RangeBound lower;
2476  RangeBound upper;
2477  bool empty;
2478  int32 cmp;
2479 
2480  range_deserialize(typcache, r, &lower, &upper, &empty);
2481 
2482  if (empty)
2483  return false;
2484 
2485  if (!lower.infinite)
2486  {
2488  typcache->rng_collation,
2489  lower.val, val));
2490  if (cmp > 0)
2491  return false;
2492  if (cmp == 0 && !lower.inclusive)
2493  return false;
2494  }
2495 
2496  if (!upper.infinite)
2497  {
2499  typcache->rng_collation,
2500  upper.val, val));
2501  if (cmp < 0)
2502  return false;
2503  if (cmp == 0 && !upper.inclusive)
2504  return false;
2505  }
2506 
2507  return true;
2508 }
FmgrInfo rng_cmp_proc_finfo
Definition: typcache.h:100
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define DatumGetInt32(X)
Definition: postgres.h:516
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
Datum val
Definition: rangetypes.h:64
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1148
signed int int32
Definition: c.h:429
bool inclusive
Definition: rangetypes.h:66
bool infinite
Definition: rangetypes.h:65
Oid rng_collation
Definition: typcache.h:99
long val
Definition: informix.c:664
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ range_contains_internal()

bool range_contains_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 2432 of file rangetypes.c.

References elog, ERROR, range_cmp_bounds(), range_deserialize(), and RangeTypeGetOid.

Referenced by range_contained_by_internal(), range_contains(), range_gist_consistent_int_range(), range_gist_consistent_leaf_range(), and spg_range_quad_leaf_consistent().

2433 {
2434  RangeBound lower1;
2435  RangeBound upper1;
2436  bool empty1;
2437  RangeBound lower2;
2438  RangeBound upper2;
2439  bool empty2;
2440 
2441  /* Different types should be prevented by ANYRANGE matching rules */
2442  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
2443  elog(ERROR, "range types do not match");
2444 
2445  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
2446  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
2447 
2448  /* If either range is empty, the answer is easy */
2449  if (empty2)
2450  return true;
2451  else if (empty1)
2452  return false;
2453 
2454  /* Else we must have lower1 <= lower2 and upper1 >= upper2 */
2455  if (range_cmp_bounds(typcache, &lower1, &lower2) > 0)
2456  return false;
2457  if (range_cmp_bounds(typcache, &upper1, &upper2) < 0)
2458  return false;
2459 
2460  return true;
2461 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define ERROR
Definition: elog.h:46
#define elog(elevel,...)
Definition: elog.h:232
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_deserialize()

void range_deserialize ( TypeCacheEntry typcache,
const RangeType range,
RangeBound lower,
RangeBound upper,
bool empty 
)

Definition at line 1788 of file rangetypes.c.

References Assert, att_addlength_pointer, att_align_pointer, fetch_att, RangeBound::inclusive, RangeBound::infinite, RangeBound::lower, RANGE_EMPTY, RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, RANGE_LB_INC, RANGE_LB_INF, RANGE_UB_INC, RANGE_UB_INF, RangeTypeGetOid, TypeCacheEntry::rngelemtype, TypeCacheEntry::typalign, typalign, TypeCacheEntry::typbyval, TypeCacheEntry::type_id, TypeCacheEntry::typlen, RangeBound::val, and VARSIZE.

Referenced by daterange_canonical(), hash_range(), hash_range_extended(), int4range_canonical(), int8range_canonical(), range_adjacent_internal(), range_after_internal(), range_before_internal(), range_cmp(), range_compare(), range_contains_elem_internal(), range_contains_internal(), range_eq_internal(), range_intersect_internal(), range_lower(), range_minus_internal(), range_out(), range_overlaps_internal(), range_overleft_internal(), range_overright_internal(), range_send(), range_split_internal(), range_union_internal(), and range_upper().

1790 {
1791  char flags;
1792  int16 typlen;
1793  bool typbyval;
1794  char typalign;
1795  Pointer ptr;
1796  Datum lbound;
1797  Datum ubound;
1798 
1799  /* assert caller passed the right typcache entry */
1800  Assert(RangeTypeGetOid(range) == typcache->type_id);
1801 
1802  /* fetch the flag byte from datum's last byte */
1803  flags = *((const char *) range + VARSIZE(range) - 1);
1804 
1805  /* fetch information about range's element type */
1806  typlen = typcache->rngelemtype->typlen;
1807  typbyval = typcache->rngelemtype->typbyval;
1808  typalign = typcache->rngelemtype->typalign;
1809 
1810  /* initialize data pointer just after the range OID */
1811  ptr = (Pointer) (range + 1);
1812 
1813  /* fetch lower bound, if any */
1814  if (RANGE_HAS_LBOUND(flags))
1815  {
1816  /* att_align_pointer cannot be necessary here */
1817  lbound = fetch_att(ptr, typbyval, typlen);
1818  ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr);
1819  }
1820  else
1821  lbound = (Datum) 0;
1822 
1823  /* fetch upper bound, if any */
1824  if (RANGE_HAS_UBOUND(flags))
1825  {
1826  ptr = (Pointer) att_align_pointer(ptr, typalign, typlen, ptr);
1827  ubound = fetch_att(ptr, typbyval, typlen);
1828  /* no need for att_addlength_pointer */
1829  }
1830  else
1831  ubound = (Datum) 0;
1832 
1833  /* emit results */
1834 
1835  *empty = (flags & RANGE_EMPTY) != 0;
1836 
1837  lower->val = lbound;
1838  lower->infinite = (flags & RANGE_LB_INF) != 0;
1839  lower->inclusive = (flags & RANGE_LB_INC) != 0;
1840  lower->lower = true;
1841 
1842  upper->val = ubound;
1843  upper->infinite = (flags & RANGE_UB_INF) != 0;
1844  upper->inclusive = (flags & RANGE_UB_INC) != 0;
1845  upper->lower = false;
1846 }
#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
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define VARSIZE(PTR)
Definition: postgres.h:316
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
#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
#define RANGE_LB_INC
Definition: rangetypes.h:39
#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

◆ range_eq_internal()

bool range_eq_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 555 of file rangetypes.c.

References elog, ERROR, range_cmp_bounds(), range_deserialize(), and RangeTypeGetOid.

Referenced by range_eq(), range_gist_consistent_leaf_range(), range_gist_same(), range_ne_internal(), and spg_range_quad_leaf_consistent().

556 {
557  RangeBound lower1,
558  lower2;
559  RangeBound upper1,
560  upper2;
561  bool empty1,
562  empty2;
563 
564  /* Different types should be prevented by ANYRANGE matching rules */
565  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
566  elog(ERROR, "range types do not match");
567 
568  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
569  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
570 
571  if (empty1 && empty2)
572  return true;
573  if (empty1 != empty2)
574  return false;
575 
576  if (range_cmp_bounds(typcache, &lower1, &lower2) != 0)
577  return false;
578 
579  if (range_cmp_bounds(typcache, &upper1, &upper2) != 0)
580  return false;
581 
582  return true;
583 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define ERROR
Definition: elog.h:46
#define elog(elevel,...)
Definition: elog.h:232
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_get_flags()

char range_get_flags ( const RangeType range)

Definition at line 1855 of file rangetypes.c.

References VARSIZE.

Referenced by get_gist_range_class(), hash_range(), hash_range_extended(), range_empty(), range_gist_same(), range_lower_inc(), range_lower_inf(), range_out(), range_send(), range_super_union(), range_upper_inc(), and range_upper_inf().

1856 {
1857  /* fetch the flag byte from datum's last byte */
1858  return *((char *) range + VARSIZE(range) - 1);
1859 }
#define VARSIZE(PTR)
Definition: postgres.h:316

◆ range_get_typcache()

TypeCacheEntry* range_get_typcache ( FunctionCallInfo  fcinfo,
Oid  rngtypid 
)

Definition at line 1635 of file rangetypes.c.

References elog, ERROR, FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_extra, lookup_type_cache(), TypeCacheEntry::rngelemtype, RangeIOData::typcache, TypeCacheEntry::type_id, and TYPECACHE_RANGE_INFO.

Referenced by daterange_canonical(), elem_contained_by_range(), hash_range(), hash_range_extended(), int4range_canonical(), int8range_canonical(), multirange_gist_consistent(), range_adjacent(), range_after(), range_before(), range_cmp(), range_constructor2(), range_constructor3(), range_contained_by(), range_contains(), range_contains_elem(), range_eq(), range_gist_consistent(), range_gist_penalty(), range_gist_picksplit(), range_gist_same(), range_gist_union(), range_intersect(), range_intersect_agg_transfn(), range_lower(), range_merge(), range_minus(), range_ne(), range_overlaps(), range_overleft(), range_overright(), range_typanalyze(), range_union(), range_upper(), rangesel(), spg_range_quad_choose(), spg_range_quad_inner_consistent(), spg_range_quad_leaf_consistent(), and spg_range_quad_picksplit().

1636 {
1637  TypeCacheEntry *typcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
1638 
1639  if (typcache == NULL ||
1640  typcache->type_id != rngtypid)
1641  {
1642  typcache = lookup_type_cache(rngtypid, TYPECACHE_RANGE_INFO);
1643  if (typcache->rngelemtype == NULL)
1644  elog(ERROR, "type %u is not a range type", rngtypid);
1645  fcinfo->flinfo->fn_extra = (void *) typcache;
1646  }
1647 
1648  return typcache;
1649 }
#define TYPECACHE_RANGE_INFO
Definition: typcache.h:147
#define ERROR
Definition: elog.h:46
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:98
FmgrInfo * flinfo
Definition: fmgr.h:87
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:339
void * fn_extra
Definition: fmgr.h:64
#define elog(elevel,...)
Definition: elog.h:232

◆ range_intersect_internal()

RangeType* range_intersect_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 1125 of file rangetypes.c.

References make_empty_range(), make_range(), range_cmp_bounds(), range_deserialize(), and range_overlaps_internal().

Referenced by multirange_intersect_internal(), range_intersect(), and range_intersect_agg_transfn().

1126 {
1127  RangeBound lower1,
1128  lower2;
1129  RangeBound upper1,
1130  upper2;
1131  bool empty1,
1132  empty2;
1133  RangeBound *result_lower;
1134  RangeBound *result_upper;
1135 
1136  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
1137  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
1138 
1139  if (empty1 || empty2 || !range_overlaps_internal(typcache, r1, r2))
1140  return make_empty_range(typcache);
1141 
1142  if (range_cmp_bounds(typcache, &lower1, &lower2) >= 0)
1143  result_lower = &lower1;
1144  else
1145  result_lower = &lower2;
1146 
1147  if (range_cmp_bounds(typcache, &upper1, &upper2) <= 0)
1148  result_upper = &upper1;
1149  else
1150  result_upper = &upper2;
1151 
1152  return make_range(typcache, result_lower, result_upper, false);
1153 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1884
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:823
RangeType * make_empty_range(TypeCacheEntry *typcache)
Definition: rangetypes.c:2073
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_minus_internal()

RangeType* range_minus_internal ( TypeCacheEntry typcache,
RangeType r1,
RangeType r2 
)

Definition at line 975 of file rangetypes.c.

References elog, ereport, errcode(), errmsg(), ERROR, RangeBound::inclusive, RangeBound::lower, make_empty_range(), make_range(), range_cmp_bounds(), and range_deserialize().

Referenced by multirange_minus_internal(), and range_minus().

976 {
977  RangeBound lower1,
978  lower2;
979  RangeBound upper1,
980  upper2;
981  bool empty1,
982  empty2;
983  int cmp_l1l2,
984  cmp_l1u2,
985  cmp_u1l2,
986  cmp_u1u2;
987 
988  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
989  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
990 
991  /* if either is empty, r1 is the correct answer */
992  if (empty1 || empty2)
993  return r1;
994 
995  cmp_l1l2 = range_cmp_bounds(typcache, &lower1, &lower2);
996  cmp_l1u2 = range_cmp_bounds(typcache, &lower1, &upper2);
997  cmp_u1l2 = range_cmp_bounds(typcache, &upper1, &lower2);
998  cmp_u1u2 = range_cmp_bounds(typcache, &upper1, &upper2);
999 
1000  if (cmp_l1l2 < 0 && cmp_u1u2 > 0)
1001  ereport(ERROR,
1002  (errcode(ERRCODE_DATA_EXCEPTION),
1003  errmsg("result of range difference would not be contiguous")));
1004 
1005  if (cmp_l1u2 > 0 || cmp_u1l2 < 0)
1006  return r1;
1007 
1008  if (cmp_l1l2 >= 0 && cmp_u1u2 <= 0)
1009  return make_empty_range(typcache);
1010 
1011  if (cmp_l1l2 <= 0 && cmp_u1l2 >= 0 && cmp_u1u2 <= 0)
1012  {
1013  lower2.inclusive = !lower2.inclusive;
1014  lower2.lower = false; /* it will become the upper bound */
1015  return make_range(typcache, &lower1, &lower2, false);
1016  }
1017 
1018  if (cmp_l1l2 >= 0 && cmp_u1u2 >= 0 && cmp_l1u2 <= 0)
1019  {
1020  upper2.inclusive = !upper2.inclusive;
1021  upper2.lower = true; /* it will become the lower bound */
1022  return make_range(typcache, &upper2, &upper1, false);
1023  }
1024 
1025  elog(ERROR, "unexpected case in range_minus");
1026  return NULL;
1027 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1884
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
int errcode(int sqlerrcode)
Definition: elog.c:698
RangeType * make_empty_range(TypeCacheEntry *typcache)
Definition: rangetypes.c:2073
bool inclusive
Definition: rangetypes.h:66
#define ERROR
Definition: elog.h:46
bool lower
Definition: rangetypes.h:67
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_ne_internal()

bool range_ne_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 600 of file rangetypes.c.

References range_eq_internal().

Referenced by range_ne().

601 {
602  return (!range_eq_internal(typcache, r1, r2));
603 }
bool range_eq_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:555

◆ range_overlaps_internal()

bool range_overlaps_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 823 of file rangetypes.c.

References elog, ERROR, range_cmp_bounds(), range_deserialize(), and RangeTypeGetOid.

Referenced by multirange_intersect_internal(), multirange_minus_internal(), range_gist_consistent_int_range(), range_gist_consistent_leaf_range(), range_intersect_internal(), range_overlaps(), range_union_internal(), and spg_range_quad_leaf_consistent().

824 {
825  RangeBound lower1,
826  lower2;
827  RangeBound upper1,
828  upper2;
829  bool empty1,
830  empty2;
831 
832  /* Different types should be prevented by ANYRANGE matching rules */
833  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
834  elog(ERROR, "range types do not match");
835 
836  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
837  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
838 
839  /* An empty range does not overlap any other range */
840  if (empty1 || empty2)
841  return false;
842 
843  if (range_cmp_bounds(typcache, &lower1, &lower2) >= 0 &&
844  range_cmp_bounds(typcache, &lower1, &upper2) <= 0)
845  return true;
846 
847  if (range_cmp_bounds(typcache, &lower2, &lower1) >= 0 &&
848  range_cmp_bounds(typcache, &lower2, &upper1) <= 0)
849  return true;
850 
851  return false;
852 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define ERROR
Definition: elog.h:46
#define elog(elevel,...)
Definition: elog.h:232
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_overleft_internal()

bool range_overleft_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 869 of file rangetypes.c.

References elog, ERROR, range_cmp_bounds(), range_deserialize(), and RangeTypeGetOid.

Referenced by multirange_intersect_internal(), range_gist_consistent_int_range(), range_gist_consistent_leaf_range(), range_overleft(), and spg_range_quad_leaf_consistent().

870 {
871  RangeBound lower1,
872  lower2;
873  RangeBound upper1,
874  upper2;
875  bool empty1,
876  empty2;
877 
878  /* Different types should be prevented by ANYRANGE matching rules */
879  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
880  elog(ERROR, "range types do not match");
881 
882  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
883  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
884 
885  /* An empty range is neither before nor after any other range */
886  if (empty1 || empty2)
887  return false;
888 
889  if (range_cmp_bounds(typcache, &upper1, &upper2) <= 0)
890  return true;
891 
892  return false;
893 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define ERROR
Definition: elog.h:46
#define elog(elevel,...)
Definition: elog.h:232
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_overright_internal()

bool range_overright_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 910 of file rangetypes.c.

References elog, ERROR, range_cmp_bounds(), range_deserialize(), and RangeTypeGetOid.

Referenced by range_gist_consistent_int_range(), range_gist_consistent_leaf_range(), range_overright(), and spg_range_quad_leaf_consistent().

911 {
912  RangeBound lower1,
913  lower2;
914  RangeBound upper1,
915  upper2;
916  bool empty1,
917  empty2;
918 
919  /* Different types should be prevented by ANYRANGE matching rules */
920  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
921  elog(ERROR, "range types do not match");
922 
923  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
924  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
925 
926  /* An empty range is neither before nor after any other range */
927  if (empty1 || empty2)
928  return false;
929 
930  if (range_cmp_bounds(typcache, &lower1, &lower2) >= 0)
931  return true;
932 
933  return false;
934 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define ERROR
Definition: elog.h:46
#define elog(elevel,...)
Definition: elog.h:232
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_serialize()

RangeType* range_serialize ( TypeCacheEntry typcache,
RangeBound lower,
RangeBound upper,
bool  empty 
)

Definition at line 1659 of file rangetypes.c.

References Assert, cmp(), datum_compute_size(), datum_write(), ereport, errcode(), errmsg(), ERROR, RangeBound::inclusive, RangeBound::infinite, RangeBound::lower, MAXALIGN, palloc0(), PG_DETOAST_DATUM_PACKED, PointerGetDatum, range(), range_cmp_bound_values(), RANGE_EMPTY, RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, RANGE_LB_INC, RANGE_LB_INF, RANGE_UB_INC, RANGE_UB_INF, RangeType::rangetypid, TypeCacheEntry::rngelemtype, SET_VARSIZE, TypeCacheEntry::typalign, typalign, TypeCacheEntry::typbyval, TypeCacheEntry::type_id, TypeCacheEntry::typlen, TypeCacheEntry::typstorage, and RangeBound::val.

Referenced by daterange_canonical(), int4range_canonical(), int8range_canonical(), and make_range().

1661 {
1662  RangeType *range;
1663  int cmp;
1664  Size msize;
1665  Pointer ptr;
1666  int16 typlen;
1667  bool typbyval;
1668  char typalign;
1669  char typstorage;
1670  char flags = 0;
1671 
1672  /*
1673  * Verify range is not invalid on its face, and construct flags value,
1674  * preventing any non-canonical combinations such as infinite+inclusive.
1675  */
1676  Assert(lower->lower);
1677  Assert(!upper->lower);
1678 
1679  if (empty)
1680  flags |= RANGE_EMPTY;
1681  else
1682  {
1683  cmp = range_cmp_bound_values(typcache, lower, upper);
1684 
1685  /* error check: if lower bound value is above upper, it's wrong */
1686  if (cmp > 0)
1687  ereport(ERROR,
1688  (errcode(ERRCODE_DATA_EXCEPTION),
1689  errmsg("range lower bound must be less than or equal to range upper bound")));
1690 
1691  /* if bounds are equal, and not both inclusive, range is empty */
1692  if (cmp == 0 && !(lower->inclusive && upper->inclusive))
1693  flags |= RANGE_EMPTY;
1694  else
1695  {
1696  /* infinite boundaries are never inclusive */
1697  if (lower->infinite)
1698  flags |= RANGE_LB_INF;
1699  else if (lower->inclusive)
1700  flags |= RANGE_LB_INC;
1701  if (upper->infinite)
1702  flags |= RANGE_UB_INF;
1703  else if (upper->inclusive)
1704  flags |= RANGE_UB_INC;
1705  }
1706  }
1707 
1708  /* Fetch information about range's element type */
1709  typlen = typcache->rngelemtype->typlen;
1710  typbyval = typcache->rngelemtype->typbyval;
1711  typalign = typcache->rngelemtype->typalign;
1712  typstorage = typcache->rngelemtype->typstorage;
1713 
1714  /* Count space for varlena header and range type's OID */
1715  msize = sizeof(RangeType);
1716  Assert(msize == MAXALIGN(msize));
1717 
1718  /* Count space for bounds */
1719  if (RANGE_HAS_LBOUND(flags))
1720  {
1721  /*
1722  * Make sure item to be inserted is not toasted. It is essential that
1723  * we not insert an out-of-line toast value pointer into a range
1724  * object, for the same reasons that arrays and records can't contain
1725  * them. It would work to store a compressed-in-line value, but we
1726  * prefer to decompress and then let compression be applied to the
1727  * whole range object if necessary. But, unlike arrays, we do allow
1728  * short-header varlena objects to stay as-is.
1729  */
1730  if (typlen == -1)
1731  lower->val = PointerGetDatum(PG_DETOAST_DATUM_PACKED(lower->val));
1732 
1733  msize = datum_compute_size(msize, lower->val, typbyval, typalign,
1734  typlen, typstorage);
1735  }
1736 
1737  if (RANGE_HAS_UBOUND(flags))
1738  {
1739  /* Make sure item to be inserted is not toasted */
1740  if (typlen == -1)
1741  upper->val = PointerGetDatum(PG_DETOAST_DATUM_PACKED(upper->val));
1742 
1743  msize = datum_compute_size(msize, upper->val, typbyval, typalign,
1744  typlen, typstorage);
1745  }
1746 
1747  /* Add space for flag byte */
1748  msize += sizeof(char);
1749 
1750  /* Note: zero-fill is required here, just as in heap tuples */
1751  range = (RangeType *) palloc0(msize);
1752  SET_VARSIZE(range, msize);
1753 
1754  /* Now fill in the datum */
1755  range->rangetypid = typcache->type_id;
1756 
1757  ptr = (char *) (range + 1);
1758 
1759  if (RANGE_HAS_LBOUND(flags))
1760  {
1761  Assert(lower->lower);
1762  ptr = datum_write(ptr, lower->val, typbyval, typalign, typlen,
1763  typstorage);
1764  }
1765 
1766  if (RANGE_HAS_UBOUND(flags))
1767  {
1768  Assert(!upper->lower);
1769  ptr = datum_write(ptr, upper->val, typbyval, typalign, typlen,
1770  typstorage);
1771  }
1772 
1773  *((char *) ptr) = flags;
1774 
1775  return range;
1776 }
#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
#define PointerGetDatum(X)
Definition: postgres.h:600
int range_cmp_bound_values(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1998
Datum val
Definition: rangetypes.h:64
int errcode(int sqlerrcode)
Definition: elog.c:698
int16 typlen
Definition: typcache.h:39
#define RANGE_LB_INF
Definition: rangetypes.h:41
bool typbyval
Definition: typcache.h:40
Oid rangetypid
Definition: rangetypes.h:28
char * Pointer
Definition: c.h:418
char typalign
Definition: pg_type.h:176
bool inclusive
Definition: rangetypes.h:66
#define ERROR
Definition: elog.h:46
#define PG_DETOAST_DATUM_PACKED(datum)
Definition: fmgr.h:248
static Size datum_compute_size(Size sz, Datum datum, bool typbyval, char typalign, int16 typlen, char typstorage)
Definition: rangetypes.c:2528
char typstorage
Definition: typcache.h:42
#define RANGE_UB_INC
Definition: rangetypes.h:40
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
bool lower
Definition: rangetypes.h:67
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:98
void * palloc0(Size size)
Definition: mcxt.c:1093
static Pointer datum_write(Pointer ptr, Datum datum, bool typbyval, char typalign, int16 typlen, char typstorage)
Definition: rangetypes.c:2554
#define RANGE_LB_INC
Definition: rangetypes.h:39
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
size_t Size
Definition: c.h:540
bool infinite
Definition: rangetypes.h:65
#define MAXALIGN(LEN)
Definition: c.h:757
#define RANGE_UB_INF
Definition: rangetypes.h:42
char typalign
Definition: typcache.h:41
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ range_set_contain_empty()

void range_set_contain_empty ( RangeType range)

Definition at line 1869 of file rangetypes.c.

References RANGE_CONTAIN_EMPTY, and VARSIZE.

Referenced by range_super_union().

1870 {
1871  char *flagsp;
1872 
1873  /* flag byte is datum's last byte */
1874  flagsp = (char *) range + VARSIZE(range) - 1;
1875 
1876  *flagsp |= RANGE_CONTAIN_EMPTY;
1877 }
#define VARSIZE(PTR)
Definition: postgres.h:316
#define RANGE_CONTAIN_EMPTY
Definition: rangetypes.h:45

◆ range_split_internal()

bool range_split_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2,
RangeType **  output1,
RangeType **  output2 
)

Definition at line 1164 of file rangetypes.c.

References RangeBound::inclusive, RangeBound::lower, make_range(), range_cmp_bounds(), and range_deserialize().

Referenced by multirange_minus_internal().

1166 {
1167  RangeBound lower1,
1168  lower2;
1169  RangeBound upper1,
1170  upper2;
1171  bool empty1,
1172  empty2;
1173 
1174  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
1175  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
1176 
1177  if (range_cmp_bounds(typcache, &lower1, &lower2) < 0 &&
1178  range_cmp_bounds(typcache, &upper1, &upper2) > 0)
1179  {
1180  /*
1181  * Need to invert inclusive/exclusive for the lower2 and upper2
1182  * points. They can't be infinite though. We're allowed to overwrite
1183  * these RangeBounds since they only exist locally.
1184  */
1185  lower2.inclusive = !lower2.inclusive;
1186  lower2.lower = false;
1187  upper2.inclusive = !upper2.inclusive;
1188  upper2.lower = true;
1189 
1190  *output1 = make_range(typcache, &lower1, &lower2, false);
1191  *output2 = make_range(typcache, &upper2, &upper1, false);
1192  return true;
1193  }
1194 
1195  return false;
1196 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1884
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
bool inclusive
Definition: rangetypes.h:66
bool lower
Definition: rangetypes.h:67
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_union_internal()

RangeType* range_union_internal ( TypeCacheEntry typcache,
RangeType r1,
RangeType r2,
bool  strict 
)

Definition at line 1034 of file rangetypes.c.

References DatumGetBool, elog, ereport, errcode(), errmsg(), ERROR, make_range(), range_adjacent_internal(), range_cmp_bounds(), range_deserialize(), range_overlaps_internal(), and RangeTypeGetOid.

Referenced by multirange_canonicalize(), range_merge(), and range_union().

1036 {
1037  RangeBound lower1,
1038  lower2;
1039  RangeBound upper1,
1040  upper2;
1041  bool empty1,
1042  empty2;
1043  RangeBound *result_lower;
1044  RangeBound *result_upper;
1045 
1046  /* Different types should be prevented by ANYRANGE matching rules */
1047  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
1048  elog(ERROR, "range types do not match");
1049 
1050  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
1051  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
1052 
1053  /* if either is empty, the other is the correct answer */
1054  if (empty1)
1055  return r2;
1056  if (empty2)
1057  return r1;
1058 
1059  if (strict &&
1060  !DatumGetBool(range_overlaps_internal(typcache, r1, r2)) &&
1061  !DatumGetBool(range_adjacent_internal(typcache, r1, r2)))
1062  ereport(ERROR,
1063  (errcode(ERRCODE_DATA_EXCEPTION),
1064  errmsg("result of range union would not be contiguous")));
1065 
1066  if (range_cmp_bounds(typcache, &lower1, &lower2) < 0)
1067  result_lower = &lower1;
1068  else
1069  result_lower = &lower2;
1070 
1071  if (range_cmp_bounds(typcache, &upper1, &upper2) > 0)
1072  result_upper = &upper1;
1073  else
1074  result_upper = &upper2;
1075 
1076  return make_range(typcache, result_lower, result_upper, false);
1077 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1884
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:823
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
int errcode(int sqlerrcode)
Definition: elog.c:698
#define ERROR
Definition: elog.h:46
#define DatumGetBool(X)
Definition: postgres.h:437
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
bool range_adjacent_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:780
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924