PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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 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

static RangeTypeDatumGetRangeTypeP (Datum X)
 
static RangeTypeDatumGetRangeTypePCopy (Datum X)
 
static Datum RangeTypePGetDatum (const RangeType *X)
 
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, struct Node *escontext)
 
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, struct Node *escontext)
 
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 boundA, RangeBound boundB)
 
RangeTypemake_empty_range (TypeCacheEntry *typcache)
 
bool range_split_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2, RangeType **output1, RangeType **output2)
 
void range_minus_multi_internal (TypeCacheEntry *typcache, RangeType *r1, RangeType *r2, RangeType **outputs, int *outputn)
 

Macro Definition Documentation

◆ PG_GETARG_RANGE_P

#define PG_GETARG_RANGE_P (   n)    DatumGetRangeTypeP(PG_GETARG_DATUM(n))

Definition at line 90 of file rangetypes.h.

◆ PG_GETARG_RANGE_P_COPY

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

Definition at line 91 of file rangetypes.h.

◆ PG_RETURN_RANGE_P

#define PG_RETURN_RANGE_P (   x)    return RangeTypePGetDatum(x)

Definition at line 92 of file rangetypes.h.

◆ 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.

63{
64 Datum val; /* the bound value, if any */
65 bool infinite; /* bound is +/- infinity */
66 bool inclusive; /* bound is inclusive (vs exclusive) */
67 bool lower; /* this is the lower (vs upper) bound */
69
70/*
71 * fmgr functions for range type objects
72 */
73static inline RangeType *
75{
76 return (RangeType *) PG_DETOAST_DATUM(X);
77}
78
79static inline RangeType *
81{
83}
84
85static inline Datum
87{
88 return PointerGetDatum(X);
89}
90
91#define PG_GETARG_RANGE_P(n) DatumGetRangeTypeP(PG_GETARG_DATUM(n))
92#define PG_GETARG_RANGE_P_COPY(n) DatumGetRangeTypePCopy(PG_GETARG_DATUM(n))
93#define PG_RETURN_RANGE_P(x) return RangeTypePGetDatum(x)
94
95/* Operator strategy numbers used in the GiST and SP-GiST range opclasses */
96/* Numbers are chosen to match up operator names with existing usages */
97#define RANGESTRAT_BEFORE RTLeftStrategyNumber
98#define RANGESTRAT_OVERLEFT RTOverLeftStrategyNumber
99#define RANGESTRAT_OVERLAPS RTOverlapStrategyNumber
100#define RANGESTRAT_OVERRIGHT RTOverRightStrategyNumber
101#define RANGESTRAT_AFTER RTRightStrategyNumber
102#define RANGESTRAT_ADJACENT RTSameStrategyNumber
103#define RANGESTRAT_CONTAINS RTContainsStrategyNumber
104#define RANGESTRAT_CONTAINED_BY RTContainedByStrategyNumber
105#define RANGESTRAT_CONTAINS_ELEM RTContainsElemStrategyNumber
106#define RANGESTRAT_EQ RTEqualStrategyNumber
107
108/*
109 * prototypes for functions defined in rangetypes.c
110 */
111
112extern bool range_contains_elem_internal(TypeCacheEntry *typcache, const RangeType *r, Datum val);
113
114/* internal versions of the above */
115extern bool range_eq_internal(TypeCacheEntry *typcache, const RangeType *r1,
116 const RangeType *r2);
117extern bool range_ne_internal(TypeCacheEntry *typcache, const RangeType *r1,
118 const RangeType *r2);
119extern bool range_contains_internal(TypeCacheEntry *typcache, const RangeType *r1,
120 const RangeType *r2);
121extern bool range_contained_by_internal(TypeCacheEntry *typcache, const RangeType *r1,
122 const RangeType *r2);
123extern bool range_before_internal(TypeCacheEntry *typcache, const RangeType *r1,
124 const RangeType *r2);
125extern bool range_after_internal(TypeCacheEntry *typcache, const RangeType *r1,
126 const RangeType *r2);
127extern bool range_adjacent_internal(TypeCacheEntry *typcache, const RangeType *r1,
128 const RangeType *r2);
129extern bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1,
130 const RangeType *r2);
131extern bool range_overleft_internal(TypeCacheEntry *typcache, const RangeType *r1,
132 const RangeType *r2);
133extern bool range_overright_internal(TypeCacheEntry *typcache, const RangeType *r1,
134 const RangeType *r2);
136 RangeType *r2, bool strict);
138 RangeType *r2);
140 const RangeType *r2);
141
142/* assorted support functions */
144 Oid rngtypid);
146 RangeBound *upper, bool empty,
147 struct Node *escontext);
148extern void range_deserialize(TypeCacheEntry *typcache, const RangeType *range,
150 bool *empty);
151extern char range_get_flags(const RangeType *range);
154 RangeBound *upper, bool empty,
155 struct Node *escontext);
156extern int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1,
157 const RangeBound *b2);
158extern int range_cmp_bound_values(TypeCacheEntry *typcache, const RangeBound *b1,
159 const RangeBound *b2);
160extern int range_compare(const void *key1, const void *key2, void *arg);
161extern bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound boundA,
163extern RangeType *make_empty_range(TypeCacheEntry *typcache);
164extern bool range_split_internal(TypeCacheEntry *typcache, const RangeType *r1,
165 const RangeType *r2, RangeType **output1,
169
170#endif /* RANGETYPES_H */
Datum arg
Definition elog.c:1322
#define PG_DETOAST_DATUM_COPY(datum)
Definition fmgr.h:242
#define PG_DETOAST_DATUM(datum)
Definition fmgr.h:240
long val
Definition informix.c:689
Datum lower(PG_FUNCTION_ARGS)
Datum upper(PG_FUNCTION_ARGS)
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342
uint64_t Datum
Definition postgres.h:70
unsigned int Oid
static int fb(int x)
bool range_ne_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition rangetypes.c:624
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
static RangeType * DatumGetRangeTypeP(Datum X)
Definition rangetypes.h:73
static RangeType * DatumGetRangeTypePCopy(Datum X)
Definition rangetypes.h:79
bool range_split_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2, RangeType **output1, RangeType **output2)
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty, struct Node *escontext)
bool range_contained_by_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty, struct Node *escontext)
bool range_contains_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
bool range_after_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition rangetypes.c:708
bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound boundA, RangeBound boundB)
Definition rangetypes.c:763
bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition rangetypes.c:847
bool range_before_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition rangetypes.c:670
bool range_overright_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition rangetypes.c:934
bool range_contains_elem_internal(TypeCacheEntry *typcache, const RangeType *r, Datum val)
RangeType * range_intersect_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
static Datum RangeTypePGetDatum(const RangeType *X)
Definition rangetypes.h:85
RangeType * range_minus_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition rangetypes.c:999
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
RangeType * range_union_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2, bool strict)
bool range_eq_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition rangetypes.c:579
bool range_adjacent_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition rangetypes.c:804
void range_set_contain_empty(RangeType *range)
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
char range_get_flags(const RangeType *range)
bool range_overleft_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition rangetypes.c:893
int range_compare(const void *key1, const void *key2, void *arg)
void range_minus_multi_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2, RangeType **outputs, int *outputn)
RangeType * make_empty_range(TypeCacheEntry *typcache)
int range_cmp_bound_values(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition nodes.h:135

◆ RANGE_EMPTY

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

Definition at line 38 of file rangetypes.h.

◆ RANGE_EMPTY_LITERAL

#define RANGE_EMPTY_LITERAL   "empty"

Definition at line 32 of file rangetypes.h.

◆ RANGE_HAS_LBOUND

#define RANGE_HAS_LBOUND (   flags)
Value:
(!((flags) & (RANGE_EMPTY | \
#define RANGE_EMPTY
Definition rangetypes.h:38
#define RANGE_LB_NULL
Definition rangetypes.h:43
#define RANGE_LB_INF
Definition rangetypes.h:41

Definition at line 47 of file rangetypes.h.

◆ RANGE_HAS_UBOUND

#define RANGE_HAS_UBOUND (   flags)
Value:
(!((flags) & (RANGE_EMPTY | \
#define RANGE_UB_INF
Definition rangetypes.h:42
#define RANGE_UB_NULL
Definition rangetypes.h:44

Definition at line 51 of file rangetypes.h.

◆ RANGE_LB_INC

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

Definition at line 39 of file rangetypes.h.

◆ RANGE_LB_INF

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

Definition at line 41 of file rangetypes.h.

◆ 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 */

Definition at line 40 of file rangetypes.h.

◆ RANGE_UB_INF

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

Definition at line 42 of file rangetypes.h.

◆ RANGE_UB_NULL

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

Definition at line 44 of file rangetypes.h.

◆ RangeIsEmpty

#define RangeIsEmpty (   r)    ((range_get_flags(r) & RANGE_EMPTY) != 0)

Definition at line 55 of file rangetypes.h.

◆ RangeIsOrContainsEmpty

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

Definition at line 56 of file rangetypes.h.

◆ RANGESTRAT_ADJACENT

#define RANGESTRAT_ADJACENT   RTSameStrategyNumber

Definition at line 101 of file rangetypes.h.

◆ RANGESTRAT_AFTER

#define RANGESTRAT_AFTER   RTRightStrategyNumber

Definition at line 100 of file rangetypes.h.

◆ RANGESTRAT_BEFORE

#define RANGESTRAT_BEFORE   RTLeftStrategyNumber

Definition at line 96 of file rangetypes.h.

◆ RANGESTRAT_CONTAINED_BY

#define RANGESTRAT_CONTAINED_BY   RTContainedByStrategyNumber

Definition at line 103 of file rangetypes.h.

◆ RANGESTRAT_CONTAINS

#define RANGESTRAT_CONTAINS   RTContainsStrategyNumber

Definition at line 102 of file rangetypes.h.

◆ RANGESTRAT_CONTAINS_ELEM

#define RANGESTRAT_CONTAINS_ELEM   RTContainsElemStrategyNumber

Definition at line 104 of file rangetypes.h.

◆ RANGESTRAT_EQ

#define RANGESTRAT_EQ   RTEqualStrategyNumber

Definition at line 105 of file rangetypes.h.

◆ RANGESTRAT_OVERLAPS

#define RANGESTRAT_OVERLAPS   RTOverlapStrategyNumber

Definition at line 98 of file rangetypes.h.

◆ RANGESTRAT_OVERLEFT

#define RANGESTRAT_OVERLEFT   RTOverLeftStrategyNumber

Definition at line 97 of file rangetypes.h.

◆ RANGESTRAT_OVERRIGHT

#define RANGESTRAT_OVERRIGHT   RTOverRightStrategyNumber

Definition at line 99 of file rangetypes.h.

◆ RangeTypeGetOid

#define RangeTypeGetOid (   r)    ((r)->rangetypid)

Definition at line 35 of file rangetypes.h.

Function Documentation

◆ bounds_adjacent()

bool bounds_adjacent ( TypeCacheEntry typcache,
RangeBound  boundA,
RangeBound  boundB 
)
extern

Definition at line 763 of file rangetypes.c.

764{
765 int cmp;
766
767 Assert(!boundA.lower && boundB.lower);
768
769 cmp = range_cmp_bound_values(typcache, &boundA, &boundB);
770 if (cmp < 0)
771 {
772 RangeType *r;
773
774 /*
775 * Bounds do not overlap; see if there are points in between.
776 */
777
778 /* in a continuous subtype, there are assumed to be points between */
779 if (!OidIsValid(typcache->rng_canonical_finfo.fn_oid))
780 return false;
781
782 /*
783 * The bounds are of a discrete range type; so make a range A..B and
784 * see if it's empty.
785 */
786
787 /* flip the inclusion flags */
788 boundA.inclusive = !boundA.inclusive;
789 boundB.inclusive = !boundB.inclusive;
790 /* change upper/lower labels to avoid Assert failures */
791 boundA.lower = true;
792 boundB.lower = false;
793 r = make_range(typcache, &boundA, &boundB, false, NULL);
794 return RangeIsEmpty(r);
795 }
796 else if (cmp == 0)
797 return boundA.inclusive != boundB.inclusive;
798 else
799 return false; /* bounds overlap */
800}
#define Assert(condition)
Definition c.h:945
#define OidIsValid(objectId)
Definition c.h:860
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty, struct Node *escontext)
int range_cmp_bound_values(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
#define RangeIsEmpty(r)
Definition rangetypes.h:55
static int cmp(const chr *x, const chr *y, size_t len)
Oid fn_oid
Definition fmgr.h:59
FmgrInfo rng_canonical_finfo
Definition typcache.h:103

References Assert, cmp(), fb(), FmgrInfo::fn_oid, 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().

◆ DatumGetRangeTypeP()

◆ DatumGetRangeTypePCopy()

static RangeType * DatumGetRangeTypePCopy ( Datum  X)
inlinestatic

Definition at line 79 of file rangetypes.h.

81{

References fb(), and PG_DETOAST_DATUM_COPY.

◆ make_empty_range()

RangeType * make_empty_range ( TypeCacheEntry typcache)
extern

Definition at line 2399 of file rangetypes.c.

2400{
2403
2404 lower.val = (Datum) 0;
2405 lower.infinite = false;
2406 lower.inclusive = false;
2407 lower.lower = true;
2408
2409 upper.val = (Datum) 0;
2410 upper.infinite = false;
2411 upper.inclusive = false;
2412 upper.lower = false;
2413
2414 return make_range(typcache, &lower, &upper, true, NULL);
2415}
Datum val
Definition rangetypes.h:63

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

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

◆ make_range()

RangeType * make_range ( TypeCacheEntry typcache,
RangeBound lower,
RangeBound upper,
bool  empty,
struct Node escontext 
)
extern

Definition at line 2186 of file rangetypes.c.

2188{
2190
2191 range = range_serialize(typcache, lower, upper, empty, escontext);
2192
2193 if (SOFT_ERROR_OCCURRED(escontext))
2194 return NULL;
2195
2196 /* no need to call canonical on empty ranges ... */
2197 if (OidIsValid(typcache->rng_canonical_finfo.fn_oid) &&
2199 {
2200 /* Do this the hard way so that we can pass escontext */
2201 LOCAL_FCINFO(fcinfo, 1);
2202 Datum result;
2203
2204 InitFunctionCallInfoData(*fcinfo, &typcache->rng_canonical_finfo, 1,
2205 InvalidOid, escontext, NULL);
2206
2207 fcinfo->args[0].value = RangeTypePGetDatum(range);
2208 fcinfo->args[0].isnull = false;
2209
2210 result = FunctionCallInvoke(fcinfo);
2211
2212 if (SOFT_ERROR_OCCURRED(escontext))
2213 return NULL;
2214
2215 /* Should not get a null result if there was no error */
2216 if (fcinfo->isnull)
2217 elog(ERROR, "function %u returned NULL",
2218 typcache->rng_canonical_finfo.fn_oid);
2219
2220 range = DatumGetRangeTypeP(result);
2221 }
2222
2223 return range;
2224}
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo)
Definition fmgr.h:150
#define LOCAL_FCINFO(name, nargs)
Definition fmgr.h:110
#define FunctionCallInvoke(fcinfo)
Definition fmgr.h:172
#define SOFT_ERROR_OCCURRED(escontext)
Definition miscnodes.h:53
#define InvalidOid
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty, struct Node *escontext)

References DatumGetRangeTypeP(), elog, ERROR, fb(), FmgrInfo::fn_oid, FunctionCallInvoke, InitFunctionCallInfoData, InvalidOid, LOCAL_FCINFO, lower(), OidIsValid, range(), range_serialize(), RangeIsEmpty, RangeTypePGetDatum(), TypeCacheEntry::rng_canonical_finfo, SOFT_ERROR_OCCURRED, and upper().

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_minus_multi_internal(), range_recv(), range_split_internal(), range_super_union(), and range_union_internal().

◆ range_adjacent_internal()

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

Definition at line 804 of file rangetypes.c.

805{
807 lower2;
809 upper2;
810 bool empty1,
811 empty2;
812
813 /* Different types should be prevented by ANYRANGE matching rules */
815 elog(ERROR, "range types do not match");
816
817 range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
818 range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
819
820 /* An empty range is not adjacent to any other range */
821 if (empty1 || empty2)
822 return false;
823
824 /*
825 * Given two ranges A..B and C..D, the ranges are adjacent if and only if
826 * B is adjacent to C, or D is adjacent to A.
827 */
828 return (bounds_adjacent(typcache, upper1, lower2) ||
829 bounds_adjacent(typcache, upper2, lower1));
830}
bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound boundA, RangeBound boundB)
Definition rangetypes.c:763
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
#define RangeTypeGetOid(r)
Definition rangetypes.h:35

References bounds_adjacent(), elog, ERROR, fb(), 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().

◆ range_after_internal()

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

Definition at line 708 of file rangetypes.c.

709{
711 lower2;
713 upper2;
714 bool empty1,
715 empty2;
716
717 /* Different types should be prevented by ANYRANGE matching rules */
719 elog(ERROR, "range types do not match");
720
721 range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
722 range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
723
724 /* An empty range is neither before nor after any other range */
725 if (empty1 || empty2)
726 return false;
727
728 return (range_cmp_bounds(typcache, &lower1, &upper2) > 0);
729}
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)

References elog, ERROR, fb(), 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().

◆ range_before_internal()

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

Definition at line 670 of file rangetypes.c.

671{
673 lower2;
675 upper2;
676 bool empty1,
677 empty2;
678
679 /* Different types should be prevented by ANYRANGE matching rules */
681 elog(ERROR, "range types do not match");
682
683 range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
684 range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
685
686 /* An empty range is neither before nor after any other range */
687 if (empty1 || empty2)
688 return false;
689
690 return (range_cmp_bounds(typcache, &upper1, &lower2) < 0);
691}

References elog, ERROR, fb(), 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().

◆ range_cmp_bound_values()

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

Definition at line 2324 of file rangetypes.c.

2326{
2327 /*
2328 * First, handle cases involving infinity, which don't require invoking
2329 * the comparison proc.
2330 */
2331 if (b1->infinite && b2->infinite)
2332 {
2333 /*
2334 * Both are infinity, so they are equal unless one is lower and the
2335 * other not.
2336 */
2337 if (b1->lower == b2->lower)
2338 return 0;
2339 else
2340 return b1->lower ? -1 : 1;
2341 }
2342 else if (b1->infinite)
2343 return b1->lower ? -1 : 1;
2344 else if (b2->infinite)
2345 return b2->lower ? 1 : -1;
2346
2347 /*
2348 * Both boundaries are finite, so compare the held values.
2349 */
2351 typcache->rng_collation,
2352 b1->val, b2->val));
2353}
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition fmgr.c:1151
static int32 DatumGetInt32(Datum X)
Definition postgres.h:202
FmgrInfo rng_cmp_proc_finfo
Definition typcache.h:102

References DatumGetInt32(), fb(), FunctionCall2Coll(), TypeCacheEntry::rng_cmp_proc_finfo, and TypeCacheEntry::rng_collation.

Referenced by bounds_adjacent(), and range_serialize().

◆ range_cmp_bounds()

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

Definition at line 2250 of file rangetypes.c.

2251{
2252 int32 result;
2253
2254 /*
2255 * First, handle cases involving infinity, which don't require invoking
2256 * the comparison proc.
2257 */
2258 if (b1->infinite && b2->infinite)
2259 {
2260 /*
2261 * Both are infinity, so they are equal unless one is lower and the
2262 * other not.
2263 */
2264 if (b1->lower == b2->lower)
2265 return 0;
2266 else
2267 return b1->lower ? -1 : 1;
2268 }
2269 else if (b1->infinite)
2270 return b1->lower ? -1 : 1;
2271 else if (b2->infinite)
2272 return b2->lower ? 1 : -1;
2273
2274 /*
2275 * Both boundaries are finite, so compare the held values.
2276 */
2278 typcache->rng_collation,
2279 b1->val, b2->val));
2280
2281 /*
2282 * If the comparison is anything other than equal, we're done. If they
2283 * compare equal though, we still have to consider whether the boundaries
2284 * are inclusive or exclusive.
2285 */
2286 if (result == 0)
2287 {
2288 if (!b1->inclusive && !b2->inclusive)
2289 {
2290 /* both are exclusive */
2291 if (b1->lower == b2->lower)
2292 return 0;
2293 else
2294 return b1->lower ? 1 : -1;
2295 }
2296 else if (!b1->inclusive)
2297 return b1->lower ? 1 : -1;
2298 else if (!b2->inclusive)
2299 return b2->lower ? -1 : 1;
2300 else
2301 {
2302 /*
2303 * Both are inclusive and the values held are equal, so they are
2304 * equal regardless of whether they are upper or lower boundaries,
2305 * or a mix.
2306 */
2307 return 0;
2308 }
2309 }
2310
2311 return result;
2312}
int32_t int32
Definition c.h:614

References DatumGetInt32(), fb(), FunctionCall2Coll(), TypeCacheEntry::rng_cmp_proc_finfo, and TypeCacheEntry::rng_collation.

Referenced by adjacent_cmp_bounds(), adjacent_inner_consistent(), bound_cmp(), calc_hist_selectivity_contained(), 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_fast_cmp(), range_gist_double_sorting_split(), range_gist_penalty(), range_intersect_internal(), range_minus_internal(), range_minus_multi_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(), rbound_bsearch(), single_bound_cmp(), and spg_range_quad_inner_consistent().

◆ range_compare()

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

Definition at line 2363 of file rangetypes.c.

2364{
2365 RangeType *r1 = *(RangeType *const *) key1;
2366 RangeType *r2 = *(RangeType *const *) key2;
2367 TypeCacheEntry *typcache = (TypeCacheEntry *) arg;
2372 bool empty1;
2373 bool empty2;
2374 int cmp;
2375
2376 range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
2377 range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
2378
2379 if (empty1 && empty2)
2380 cmp = 0;
2381 else if (empty1)
2382 cmp = -1;
2383 else if (empty2)
2384 cmp = 1;
2385 else
2386 {
2387 cmp = range_cmp_bounds(typcache, &lower1, &lower2);
2388 if (cmp == 0)
2389 cmp = range_cmp_bounds(typcache, &upper1, &upper2);
2390 }
2391
2392 return cmp;
2393}

References arg, cmp(), fb(), range_cmp_bounds(), and range_deserialize().

Referenced by multirange_canonicalize().

◆ range_contained_by_internal()

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

Definition at line 2852 of file rangetypes.c.

2853{
2854 return range_contains_internal(typcache, r2, r1);
2855}
bool range_contains_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)

References fb(), and range_contains_internal().

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

◆ range_contains_elem_internal()

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

Definition at line 2861 of file rangetypes.c.

2862{
2865 bool empty;
2866 int32 cmp;
2867
2868 range_deserialize(typcache, r, &lower, &upper, &empty);
2869
2870 if (empty)
2871 return false;
2872
2873 if (!lower.infinite)
2874 {
2876 typcache->rng_collation,
2877 lower.val, val));
2878 if (cmp > 0)
2879 return false;
2880 if (cmp == 0 && !lower.inclusive)
2881 return false;
2882 }
2883
2884 if (!upper.infinite)
2885 {
2887 typcache->rng_collation,
2888 upper.val, val));
2889 if (cmp < 0)
2890 return false;
2891 if (cmp == 0 && !upper.inclusive)
2892 return false;
2893 }
2894
2895 return true;
2896}

References cmp(), DatumGetInt32(), FunctionCall2Coll(), lower(), range_deserialize(), TypeCacheEntry::rng_cmp_proc_finfo, TypeCacheEntry::rng_collation, upper(), and 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().

◆ range_contains_internal()

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

Definition at line 2820 of file rangetypes.c.

2821{
2824 bool empty1;
2827 bool empty2;
2828
2829 /* Different types should be prevented by ANYRANGE matching rules */
2831 elog(ERROR, "range types do not match");
2832
2833 range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
2834 range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
2835
2836 /* If either range is empty, the answer is easy */
2837 if (empty2)
2838 return true;
2839 else if (empty1)
2840 return false;
2841
2842 /* Else we must have lower1 <= lower2 and upper1 >= upper2 */
2843 if (range_cmp_bounds(typcache, &lower1, &lower2) > 0)
2844 return false;
2845 if (range_cmp_bounds(typcache, &upper1, &upper2) < 0)
2846 return false;
2847
2848 return true;
2849}

References elog, ERROR, fb(), 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().

◆ range_deserialize()

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

Definition at line 2090 of file rangetypes.c.

2092{
2093 char flags;
2094 int16 typlen;
2095 bool typbyval;
2096 char typalign;
2097 const char *ptr;
2098 Datum lbound;
2099 Datum ubound;
2100
2101 /* assert caller passed the right typcache entry */
2102 Assert(RangeTypeGetOid(range) == typcache->type_id);
2103
2104 /* fetch the flag byte from datum's last byte */
2105 flags = *((const char *) range + VARSIZE(range) - 1);
2106
2107 /* fetch information about range's element type */
2108 typlen = typcache->rngelemtype->typlen;
2109 typbyval = typcache->rngelemtype->typbyval;
2110 typalign = typcache->rngelemtype->typalign;
2111
2112 /* initialize data pointer just after the range OID */
2113 ptr = (const char *) (range + 1);
2114
2115 /* fetch lower bound, if any */
2116 if (RANGE_HAS_LBOUND(flags))
2117 {
2118 /* att_align_pointer cannot be necessary here */
2119 lbound = fetch_att(ptr, typbyval, typlen);
2120 ptr = (char *) att_addlength_pointer(ptr, typlen, ptr);
2121 }
2122 else
2123 lbound = (Datum) 0;
2124
2125 /* fetch upper bound, if any */
2126 if (RANGE_HAS_UBOUND(flags))
2127 {
2128 ptr = (char *) att_align_pointer(ptr, typalign, typlen, ptr);
2129 ubound = fetch_att(ptr, typbyval, typlen);
2130 /* no need for att_addlength_pointer */
2131 }
2132 else
2133 ubound = (Datum) 0;
2134
2135 /* emit results */
2136
2137 *empty = (flags & RANGE_EMPTY) != 0;
2138
2139 lower->val = lbound;
2140 lower->infinite = (flags & RANGE_LB_INF) != 0;
2141 lower->inclusive = (flags & RANGE_LB_INC) != 0;
2142 lower->lower = true;
2143
2144 upper->val = ubound;
2145 upper->infinite = (flags & RANGE_UB_INF) != 0;
2146 upper->inclusive = (flags & RANGE_UB_INC) != 0;
2147 upper->lower = false;
2148}
int16_t int16
Definition c.h:613
char typalign
Definition pg_type.h:178
#define RANGE_HAS_UBOUND(flags)
Definition rangetypes.h:51
#define RANGE_UB_INC
Definition rangetypes.h:40
#define RANGE_LB_INC
Definition rangetypes.h:39
#define RANGE_HAS_LBOUND(flags)
Definition rangetypes.h:47
struct TypeCacheEntry * rngelemtype
Definition typcache.h:99
#define att_align_pointer(cur_offset, attalign, attlen, attptr)
Definition tupmacs.h:372
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition tupmacs.h:431
static Datum fetch_att(const void *T, bool attbyval, int attlen)
Definition tupmacs.h:108
static Size VARSIZE(const void *PTR)
Definition varatt.h:298

References Assert, att_addlength_pointer, att_align_pointer, fb(), fetch_att(), lower(), range(), RANGE_EMPTY, RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, RANGE_LB_INC, RANGE_LB_INF, RANGE_UB_INC, RANGE_UB_INF, RangeTypeGetOid, TypeCacheEntry::rngelemtype, typalign, TypeCacheEntry::typalign, TypeCacheEntry::typbyval, TypeCacheEntry::type_id, TypeCacheEntry::typlen, upper(), and VARSIZE().

Referenced by calc_hist_selectivity(), calc_hist_selectivity(), compute_range_stats(), daterange_canonical(), find_simplified_clause(), getQuadrant(), hash_range(), hash_range_extended(), int4range_canonical(), int8range_canonical(), multirange_contains_range_internal(), multirange_overleft_range(), multirange_overright_range(), multirange_union_range_equal(), range_adjacent_internal(), range_adjacent_multirange_internal(), range_after_internal(), range_after_multirange_internal(), range_before_internal(), range_before_multirange_internal(), range_cmp(), range_compare(), range_contains_elem_internal(), range_contains_internal(), range_contains_multirange_internal(), range_eq_internal(), range_fast_cmp(), range_gist_double_sorting_split(), range_gist_penalty(), range_gist_single_sorting_split(), range_intersect_internal(), range_lower(), range_minus_internal(), range_minus_multi_internal(), range_out(), range_overlaps_internal(), range_overlaps_multirange_internal(), range_overleft_internal(), range_overleft_multirange_internal(), range_overright_internal(), range_overright_multirange_internal(), range_send(), range_split_internal(), range_super_union(), range_union_internal(), range_upper(), spg_range_quad_inner_consistent(), and spg_range_quad_picksplit().

◆ range_eq_internal()

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

Definition at line 579 of file rangetypes.c.

580{
582 lower2;
584 upper2;
585 bool empty1,
586 empty2;
587
588 /* Different types should be prevented by ANYRANGE matching rules */
590 elog(ERROR, "range types do not match");
591
592 range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
593 range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
594
595 if (empty1 && empty2)
596 return true;
597 if (empty1 != empty2)
598 return false;
599
600 if (range_cmp_bounds(typcache, &lower1, &lower2) != 0)
601 return false;
602
603 if (range_cmp_bounds(typcache, &upper1, &upper2) != 0)
604 return false;
605
606 return true;
607}

References elog, ERROR, fb(), 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().

◆ range_get_flags()

char range_get_flags ( const RangeType range)
extern

Definition at line 2157 of file rangetypes.c.

2158{
2159 /* fetch the flag byte from datum's last byte */
2160 return *((const char *) range + VARSIZE(range) - 1);
2161}

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

◆ range_get_typcache()

TypeCacheEntry * range_get_typcache ( FunctionCallInfo  fcinfo,
Oid  rngtypid 
)
extern

Definition at line 1937 of file rangetypes.c.

1938{
1939 TypeCacheEntry *typcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
1940
1941 if (typcache == NULL ||
1942 typcache->type_id != rngtypid)
1943 {
1945 if (typcache->rngelemtype == NULL)
1946 elog(ERROR, "type %u is not a range type", rngtypid);
1947 fcinfo->flinfo->fn_extra = typcache;
1948 }
1949
1950 return typcache;
1951}
void * fn_extra
Definition fmgr.h:64
FmgrInfo * flinfo
Definition fmgr.h:87
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition typcache.c:389
#define TYPECACHE_RANGE_INFO
Definition typcache.h:149

References elog, ERROR, fb(), FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_extra, lookup_type_cache(), TypeCacheEntry::rngelemtype, 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().

◆ range_intersect_internal()

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

Definition at line 1149 of file rangetypes.c.

1150{
1152 lower2;
1154 upper2;
1155 bool empty1,
1156 empty2;
1159
1160 range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
1161 range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
1162
1163 if (empty1 || empty2 || !range_overlaps_internal(typcache, r1, r2))
1164 return make_empty_range(typcache);
1165
1166 if (range_cmp_bounds(typcache, &lower1, &lower2) >= 0)
1168 else
1170
1171 if (range_cmp_bounds(typcache, &upper1, &upper2) <= 0)
1173 else
1175
1176 return make_range(typcache, result_lower, result_upper, false, NULL);
1177}
bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition rangetypes.c:847
RangeType * make_empty_range(TypeCacheEntry *typcache)

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

◆ range_minus_internal()

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

Definition at line 999 of file rangetypes.c.

1000{
1002 lower2;
1004 upper2;
1005 bool empty1,
1006 empty2;
1007 int cmp_l1l2,
1008 cmp_l1u2,
1009 cmp_u1l2,
1010 cmp_u1u2;
1011
1012 range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
1013 range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
1014
1015 /* if either is empty, r1 is the correct answer */
1016 if (empty1 || empty2)
1017 return r1;
1018
1019 cmp_l1l2 = range_cmp_bounds(typcache, &lower1, &lower2);
1020 cmp_l1u2 = range_cmp_bounds(typcache, &lower1, &upper2);
1021 cmp_u1l2 = range_cmp_bounds(typcache, &upper1, &lower2);
1022 cmp_u1u2 = range_cmp_bounds(typcache, &upper1, &upper2);
1023
1025 ereport(ERROR,
1027 errmsg("result of range difference would not be contiguous")));
1028
1029 if (cmp_l1u2 > 0 || cmp_u1l2 < 0)
1030 return r1;
1031
1032 if (cmp_l1l2 >= 0 && cmp_u1u2 <= 0)
1033 return make_empty_range(typcache);
1034
1036 {
1037 lower2.inclusive = !lower2.inclusive;
1038 lower2.lower = false; /* it will become the upper bound */
1039 return make_range(typcache, &lower1, &lower2, false, NULL);
1040 }
1041
1042 if (cmp_l1l2 >= 0 && cmp_u1u2 >= 0 && cmp_l1u2 <= 0)
1043 {
1044 upper2.inclusive = !upper2.inclusive;
1045 upper2.lower = true; /* it will become the lower bound */
1046 return make_range(typcache, &upper2, &upper1, false, NULL);
1047 }
1048
1049 elog(ERROR, "unexpected case in range_minus");
1050 return NULL;
1051}
int errcode(int sqlerrcode)
Definition elog.c:874
#define ereport(elevel,...)
Definition elog.h:150
static char * errmsg

References elog, ereport, errcode(), errmsg, ERROR, fb(), make_empty_range(), make_range(), range_cmp_bounds(), and range_deserialize().

Referenced by multirange_minus_internal(), and range_minus().

◆ range_minus_multi_internal()

void range_minus_multi_internal ( TypeCacheEntry typcache,
RangeType r1,
RangeType r2,
RangeType **  outputs,
int outputn 
)
extern

Definition at line 1308 of file rangetypes.c.

1310{
1311 int cmp_l1l2,
1312 cmp_l1u2,
1313 cmp_u1l2,
1314 cmp_u1u2;
1316 lower2;
1318 upper2;
1319 bool empty1,
1320 empty2;
1321
1322 range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
1323 range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
1324
1325 if (empty1)
1326 {
1327 /* if r1 is empty then r1 - r2 is empty, so return zero results */
1328 *outputn = 0;
1329 return;
1330 }
1331 else if (empty2)
1332 {
1333 /* r2 is empty so the result is just r1 (which we know is not empty) */
1334 outputs[0] = r1;
1335 *outputn = 1;
1336 return;
1337 }
1338
1339 /*
1340 * Use the same logic as range_minus_internal, but support the split case
1341 */
1342 cmp_l1l2 = range_cmp_bounds(typcache, &lower1, &lower2);
1343 cmp_l1u2 = range_cmp_bounds(typcache, &lower1, &upper2);
1344 cmp_u1l2 = range_cmp_bounds(typcache, &upper1, &lower2);
1345 cmp_u1u2 = range_cmp_bounds(typcache, &upper1, &upper2);
1346
1348 {
1349 lower2.inclusive = !lower2.inclusive;
1350 lower2.lower = false; /* it will become the upper bound */
1351 outputs[0] = make_range(typcache, &lower1, &lower2, false, NULL);
1352
1353 upper2.inclusive = !upper2.inclusive;
1354 upper2.lower = true; /* it will become the lower bound */
1355 outputs[1] = make_range(typcache, &upper2, &upper1, false, NULL);
1356
1357 *outputn = 2;
1358 }
1359 else if (cmp_l1u2 > 0 || cmp_u1l2 < 0)
1360 {
1361 outputs[0] = r1;
1362 *outputn = 1;
1363 }
1364 else if (cmp_l1l2 >= 0 && cmp_u1u2 <= 0)
1365 {
1366 *outputn = 0;
1367 }
1368 else if (cmp_l1l2 <= 0 && cmp_u1l2 >= 0 && cmp_u1u2 <= 0)
1369 {
1370 lower2.inclusive = !lower2.inclusive;
1371 lower2.lower = false; /* it will become the upper bound */
1372 outputs[0] = make_range(typcache, &lower1, &lower2, false, NULL);
1373 *outputn = 1;
1374 }
1375 else if (cmp_l1l2 >= 0 && cmp_u1u2 >= 0 && cmp_l1u2 <= 0)
1376 {
1377 upper2.inclusive = !upper2.inclusive;
1378 upper2.lower = true; /* it will become the lower bound */
1379 outputs[0] = make_range(typcache, &upper2, &upper1, false, NULL);
1380 *outputn = 1;
1381 }
1382 else
1383 {
1384 elog(ERROR, "unexpected case in range_minus_multi");
1385 }
1386}

References elog, ERROR, fb(), make_range(), range_cmp_bounds(), and range_deserialize().

Referenced by range_minus_multi().

◆ range_ne_internal()

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

Definition at line 624 of file rangetypes.c.

625{
626 return (!range_eq_internal(typcache, r1, r2));
627}
bool range_eq_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition rangetypes.c:579

References fb(), and range_eq_internal().

Referenced by range_ne().

◆ range_overlaps_internal()

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

Definition at line 847 of file rangetypes.c.

848{
850 lower2;
852 upper2;
853 bool empty1,
854 empty2;
855
856 /* Different types should be prevented by ANYRANGE matching rules */
858 elog(ERROR, "range types do not match");
859
860 range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
861 range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
862
863 /* An empty range does not overlap any other range */
864 if (empty1 || empty2)
865 return false;
866
867 if (range_cmp_bounds(typcache, &lower1, &lower2) >= 0 &&
868 range_cmp_bounds(typcache, &lower1, &upper2) <= 0)
869 return true;
870
871 if (range_cmp_bounds(typcache, &lower2, &lower1) >= 0 &&
872 range_cmp_bounds(typcache, &lower2, &upper1) <= 0)
873 return true;
874
875 return false;
876}

References elog, ERROR, fb(), 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().

◆ range_overleft_internal()

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

Definition at line 893 of file rangetypes.c.

894{
896 lower2;
898 upper2;
899 bool empty1,
900 empty2;
901
902 /* Different types should be prevented by ANYRANGE matching rules */
904 elog(ERROR, "range types do not match");
905
906 range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
907 range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
908
909 /* An empty range is neither before nor after any other range */
910 if (empty1 || empty2)
911 return false;
912
913 if (range_cmp_bounds(typcache, &upper1, &upper2) <= 0)
914 return true;
915
916 return false;
917}

References elog, ERROR, fb(), 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().

◆ range_overright_internal()

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

Definition at line 934 of file rangetypes.c.

935{
937 lower2;
939 upper2;
940 bool empty1,
941 empty2;
942
943 /* Different types should be prevented by ANYRANGE matching rules */
945 elog(ERROR, "range types do not match");
946
947 range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
948 range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
949
950 /* An empty range is neither before nor after any other range */
951 if (empty1 || empty2)
952 return false;
953
954 if (range_cmp_bounds(typcache, &lower1, &lower2) >= 0)
955 return true;
956
957 return false;
958}

References elog, ERROR, fb(), 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().

◆ range_serialize()

RangeType * range_serialize ( TypeCacheEntry typcache,
RangeBound lower,
RangeBound upper,
bool  empty,
struct Node escontext 
)
extern

Definition at line 1961 of file rangetypes.c.

1963{
1965 int cmp;
1966 Size msize;
1967 Pointer ptr;
1968 int16 typlen;
1969 bool typbyval;
1970 char typalign;
1971 char typstorage;
1972 char flags = 0;
1973
1974 /*
1975 * Verify range is not invalid on its face, and construct flags value,
1976 * preventing any non-canonical combinations such as infinite+inclusive.
1977 */
1978 Assert(lower->lower);
1979 Assert(!upper->lower);
1980
1981 if (empty)
1982 flags |= RANGE_EMPTY;
1983 else
1984 {
1985 cmp = range_cmp_bound_values(typcache, lower, upper);
1986
1987 /* error check: if lower bound value is above upper, it's wrong */
1988 if (cmp > 0)
1989 ereturn(escontext, NULL,
1991 errmsg("range lower bound must be less than or equal to range upper bound")));
1992
1993 /* if bounds are equal, and not both inclusive, range is empty */
1994 if (cmp == 0 && !(lower->inclusive && upper->inclusive))
1995 flags |= RANGE_EMPTY;
1996 else
1997 {
1998 /* infinite boundaries are never inclusive */
1999 if (lower->infinite)
2000 flags |= RANGE_LB_INF;
2001 else if (lower->inclusive)
2002 flags |= RANGE_LB_INC;
2003 if (upper->infinite)
2004 flags |= RANGE_UB_INF;
2005 else if (upper->inclusive)
2006 flags |= RANGE_UB_INC;
2007 }
2008 }
2009
2010 /* Fetch information about range's element type */
2011 typlen = typcache->rngelemtype->typlen;
2012 typbyval = typcache->rngelemtype->typbyval;
2013 typalign = typcache->rngelemtype->typalign;
2014 typstorage = typcache->rngelemtype->typstorage;
2015
2016 /* Count space for varlena header and range type's OID */
2017 msize = sizeof(RangeType);
2019
2020 /* Count space for bounds */
2021 if (RANGE_HAS_LBOUND(flags))
2022 {
2023 /*
2024 * Make sure item to be inserted is not toasted. It is essential that
2025 * we not insert an out-of-line toast value pointer into a range
2026 * object, for the same reasons that arrays and records can't contain
2027 * them. It would work to store a compressed-in-line value, but we
2028 * prefer to decompress and then let compression be applied to the
2029 * whole range object if necessary. But, unlike arrays, we do allow
2030 * short-header varlena objects to stay as-is.
2031 */
2032 if (typlen == -1)
2034
2035 msize = datum_compute_size(msize, lower->val, typbyval, typalign,
2036 typlen, typstorage);
2037 }
2038
2039 if (RANGE_HAS_UBOUND(flags))
2040 {
2041 /* Make sure item to be inserted is not toasted */
2042 if (typlen == -1)
2044
2045 msize = datum_compute_size(msize, upper->val, typbyval, typalign,
2046 typlen, typstorage);
2047 }
2048
2049 /* Add space for flag byte */
2050 msize += sizeof(char);
2051
2052 /* Note: zero-fill is required here, just as in heap tuples */
2055
2056 /* Now fill in the datum */
2057 range->rangetypid = typcache->type_id;
2058
2059 ptr = (char *) (range + 1);
2060
2061 if (RANGE_HAS_LBOUND(flags))
2062 {
2063 Assert(lower->lower);
2064 ptr = datum_write(ptr, lower->val, typbyval, typalign, typlen,
2065 typstorage);
2066 }
2067
2068 if (RANGE_HAS_UBOUND(flags))
2069 {
2070 Assert(!upper->lower);
2071 ptr = datum_write(ptr, upper->val, typbyval, typalign, typlen,
2072 typstorage);
2073 }
2074
2075 *((char *) ptr) = flags;
2076
2077 return range;
2078}
#define MAXALIGN(LEN)
Definition c.h:898
void * Pointer
Definition c.h:609
size_t Size
Definition c.h:691
#define ereturn(context, dummy_value,...)
Definition elog.h:278
#define PG_DETOAST_DATUM_PACKED(datum)
Definition fmgr.h:248
void * palloc0(Size size)
Definition mcxt.c:1417
static char * datum_write(char *ptr, Datum datum, bool typbyval, char typalign, int16 typlen, char typstorage)
static Size datum_compute_size(Size data_length, Datum val, bool typbyval, char typalign, int16 typlen, char typstorage)
char typstorage
Definition typcache.h:42
static void SET_VARSIZE(void *PTR, Size len)
Definition varatt.h:432

References Assert, cmp(), datum_compute_size(), datum_write(), ereturn, errcode(), errmsg, fb(), 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, TypeCacheEntry::rngelemtype, SET_VARSIZE(), typalign, TypeCacheEntry::typalign, TypeCacheEntry::typbyval, TypeCacheEntry::type_id, TypeCacheEntry::typlen, TypeCacheEntry::typstorage, and upper().

Referenced by compute_range_stats(), daterange_canonical(), int4range_canonical(), int8range_canonical(), make_range(), multirangesel(), rangesel(), and spg_range_quad_picksplit().

◆ range_set_contain_empty()

void range_set_contain_empty ( RangeType range)
extern

Definition at line 2171 of file rangetypes.c.

2172{
2173 char *flagsp;
2174
2175 /* flag byte is datum's last byte */
2176 flagsp = (char *) range + VARSIZE(range) - 1;
2177
2179}
#define RANGE_CONTAIN_EMPTY
Definition rangetypes.h:45

References fb(), range(), RANGE_CONTAIN_EMPTY, and VARSIZE().

Referenced by range_super_union().

◆ range_split_internal()

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

Definition at line 1188 of file rangetypes.c.

1190{
1192 lower2;
1194 upper2;
1195 bool empty1,
1196 empty2;
1197
1198 range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
1199 range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
1200
1201 if (range_cmp_bounds(typcache, &lower1, &lower2) < 0 &&
1202 range_cmp_bounds(typcache, &upper1, &upper2) > 0)
1203 {
1204 /*
1205 * Need to invert inclusive/exclusive for the lower2 and upper2
1206 * points. They can't be infinite though. We're allowed to overwrite
1207 * these RangeBounds since they only exist locally.
1208 */
1209 lower2.inclusive = !lower2.inclusive;
1210 lower2.lower = false;
1211 upper2.inclusive = !upper2.inclusive;
1212 upper2.lower = true;
1213
1214 *output1 = make_range(typcache, &lower1, &lower2, false, NULL);
1215 *output2 = make_range(typcache, &upper2, &upper1, false, NULL);
1216 return true;
1217 }
1218
1219 return false;
1220}

References fb(), make_range(), range_cmp_bounds(), and range_deserialize().

Referenced by multirange_minus_internal().

◆ range_union_internal()

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

Definition at line 1058 of file rangetypes.c.

1060{
1062 lower2;
1064 upper2;
1065 bool empty1,
1066 empty2;
1069
1070 /* Different types should be prevented by ANYRANGE matching rules */
1072 elog(ERROR, "range types do not match");
1073
1074 range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
1075 range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
1076
1077 /* if either is empty, the other is the correct answer */
1078 if (empty1)
1079 return r2;
1080 if (empty2)
1081 return r1;
1082
1083 if (strict &&
1084 !range_overlaps_internal(typcache, r1, r2) &&
1085 !range_adjacent_internal(typcache, r1, r2))
1086 ereport(ERROR,
1088 errmsg("result of range union would not be contiguous")));
1089
1090 if (range_cmp_bounds(typcache, &lower1, &lower2) < 0)
1092 else
1094
1095 if (range_cmp_bounds(typcache, &upper1, &upper2) > 0)
1097 else
1099
1100 return make_range(typcache, result_lower, result_upper, false, NULL);
1101}
bool range_adjacent_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition rangetypes.c:804

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

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

◆ RangeTypePGetDatum()