Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * rangetypes.h
4 : * Declarations for Postgres range types.
5 : *
6 : *
7 : * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
8 : * Portions Copyright (c) 1994, Regents of the University of California
9 : *
10 : * src/include/utils/rangetypes.h
11 : *
12 : *-------------------------------------------------------------------------
13 : */
14 : #ifndef RANGETYPES_H
15 : #define RANGETYPES_H
16 :
17 : #include "utils/typcache.h"
18 :
19 :
20 : /*
21 : * Ranges are varlena objects, so must meet the varlena convention that
22 : * the first int32 of the object contains the total object size in bytes.
23 : * Be sure to use VARSIZE() and SET_VARSIZE() to access it, though!
24 : */
25 : typedef struct
26 : {
27 : int32 vl_len_; /* varlena header (do not touch directly!) */
28 : Oid rangetypid; /* range type's own OID */
29 : /* Following the OID are zero to two bound values, then a flags byte */
30 : } RangeType;
31 :
32 : #define RANGE_EMPTY_LITERAL "empty"
33 :
34 : /* Use this macro in preference to fetching rangetypid field directly */
35 : #define RangeTypeGetOid(r) ((r)->rangetypid)
36 :
37 : /* A range's flags byte contains these bits: */
38 : #define RANGE_EMPTY 0x01 /* range is empty */
39 : #define RANGE_LB_INC 0x02 /* lower bound is inclusive */
40 : #define RANGE_UB_INC 0x04 /* upper bound is inclusive */
41 : #define RANGE_LB_INF 0x08 /* lower bound is -infinity */
42 : #define RANGE_UB_INF 0x10 /* upper bound is +infinity */
43 : #define RANGE_LB_NULL 0x20 /* lower bound is null (NOT USED) */
44 : #define RANGE_UB_NULL 0x40 /* upper bound is null (NOT USED) */
45 : #define RANGE_CONTAIN_EMPTY 0x80 /* marks a GiST internal-page entry whose
46 : * subtree contains some empty ranges */
47 :
48 : #define RANGE_HAS_LBOUND(flags) (!((flags) & (RANGE_EMPTY | \
49 : RANGE_LB_NULL | \
50 : RANGE_LB_INF)))
51 :
52 : #define RANGE_HAS_UBOUND(flags) (!((flags) & (RANGE_EMPTY | \
53 : RANGE_UB_NULL | \
54 : RANGE_UB_INF)))
55 :
56 : #define RangeIsEmpty(r) ((range_get_flags(r) & RANGE_EMPTY) != 0)
57 : #define RangeIsOrContainsEmpty(r) \
58 : ((range_get_flags(r) & (RANGE_EMPTY | RANGE_CONTAIN_EMPTY)) != 0)
59 :
60 :
61 : /* Internal representation of either bound of a range (not what's on disk) */
62 : typedef struct
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 */
68 : } RangeBound;
69 :
70 : /*
71 : * fmgr functions for range type objects
72 : */
73 : static inline RangeType *
74 10351598 : DatumGetRangeTypeP(Datum X)
75 : {
76 10351598 : return (RangeType *) PG_DETOAST_DATUM(X);
77 : }
78 :
79 : static inline RangeType *
80 : DatumGetRangeTypePCopy(Datum X)
81 : {
82 : return (RangeType *) PG_DETOAST_DATUM_COPY(X);
83 : }
84 :
85 : static inline Datum
86 1962120 : RangeTypePGetDatum(const RangeType *X)
87 : {
88 1962120 : 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 :
112 : extern bool range_contains_elem_internal(TypeCacheEntry *typcache, const RangeType *r, Datum val);
113 :
114 : /* internal versions of the above */
115 : extern bool range_eq_internal(TypeCacheEntry *typcache, const RangeType *r1,
116 : const RangeType *r2);
117 : extern bool range_ne_internal(TypeCacheEntry *typcache, const RangeType *r1,
118 : const RangeType *r2);
119 : extern bool range_contains_internal(TypeCacheEntry *typcache, const RangeType *r1,
120 : const RangeType *r2);
121 : extern bool range_contained_by_internal(TypeCacheEntry *typcache, const RangeType *r1,
122 : const RangeType *r2);
123 : extern bool range_before_internal(TypeCacheEntry *typcache, const RangeType *r1,
124 : const RangeType *r2);
125 : extern bool range_after_internal(TypeCacheEntry *typcache, const RangeType *r1,
126 : const RangeType *r2);
127 : extern bool range_adjacent_internal(TypeCacheEntry *typcache, const RangeType *r1,
128 : const RangeType *r2);
129 : extern bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1,
130 : const RangeType *r2);
131 : extern bool range_overleft_internal(TypeCacheEntry *typcache, const RangeType *r1,
132 : const RangeType *r2);
133 : extern bool range_overright_internal(TypeCacheEntry *typcache, const RangeType *r1,
134 : const RangeType *r2);
135 : extern RangeType *range_union_internal(TypeCacheEntry *typcache, RangeType *r1,
136 : RangeType *r2, bool strict);
137 : extern RangeType *range_minus_internal(TypeCacheEntry *typcache, RangeType *r1,
138 : RangeType *r2);
139 : extern RangeType *range_intersect_internal(TypeCacheEntry *typcache, const RangeType *r1,
140 : const RangeType *r2);
141 :
142 : /* assorted support functions */
143 : extern TypeCacheEntry *range_get_typcache(FunctionCallInfo fcinfo,
144 : Oid rngtypid);
145 : extern RangeType *range_serialize(TypeCacheEntry *typcache, RangeBound *lower,
146 : RangeBound *upper, bool empty,
147 : struct Node *escontext);
148 : extern void range_deserialize(TypeCacheEntry *typcache, const RangeType *range,
149 : RangeBound *lower, RangeBound *upper,
150 : bool *empty);
151 : extern char range_get_flags(const RangeType *range);
152 : extern void range_set_contain_empty(RangeType *range);
153 : extern RangeType *make_range(TypeCacheEntry *typcache, RangeBound *lower,
154 : RangeBound *upper, bool empty,
155 : struct Node *escontext);
156 : extern int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1,
157 : const RangeBound *b2);
158 : extern int range_cmp_bound_values(TypeCacheEntry *typcache, const RangeBound *b1,
159 : const RangeBound *b2);
160 : extern int range_compare(const void *key1, const void *key2, void *arg);
161 : extern bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound boundA,
162 : RangeBound boundB);
163 : extern RangeType *make_empty_range(TypeCacheEntry *typcache);
164 : extern bool range_split_internal(TypeCacheEntry *typcache, const RangeType *r1,
165 : const RangeType *r2, RangeType **output1,
166 : RangeType **output2);
167 :
168 : #endif /* RANGETYPES_H */
|