1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * rangetypes.h |
4 | * Declarations for Postgres range types. |
5 | * |
6 | * |
7 | * Portions Copyright (c) 1996-2019, 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 | /* Use this macro in preference to fetching rangetypid field directly */ |
33 | #define RangeTypeGetOid(r) ((r)->rangetypid) |
34 | |
35 | /* A range's flags byte contains these bits: */ |
36 | #define RANGE_EMPTY 0x01 /* range is empty */ |
37 | #define RANGE_LB_INC 0x02 /* lower bound is inclusive */ |
38 | #define RANGE_UB_INC 0x04 /* upper bound is inclusive */ |
39 | #define RANGE_LB_INF 0x08 /* lower bound is -infinity */ |
40 | #define RANGE_UB_INF 0x10 /* upper bound is +infinity */ |
41 | #define RANGE_LB_NULL 0x20 /* lower bound is null (NOT USED) */ |
42 | #define RANGE_UB_NULL 0x40 /* upper bound is null (NOT USED) */ |
43 | #define RANGE_CONTAIN_EMPTY 0x80 /* marks a GiST internal-page entry whose |
44 | * subtree contains some empty ranges */ |
45 | |
46 | #define RANGE_HAS_LBOUND(flags) (!((flags) & (RANGE_EMPTY | \ |
47 | RANGE_LB_NULL | \ |
48 | RANGE_LB_INF))) |
49 | |
50 | #define RANGE_HAS_UBOUND(flags) (!((flags) & (RANGE_EMPTY | \ |
51 | RANGE_UB_NULL | \ |
52 | RANGE_UB_INF))) |
53 | |
54 | #define RangeIsEmpty(r) ((range_get_flags(r) & RANGE_EMPTY) != 0) |
55 | #define RangeIsOrContainsEmpty(r) \ |
56 | ((range_get_flags(r) & (RANGE_EMPTY | RANGE_CONTAIN_EMPTY)) != 0) |
57 | |
58 | |
59 | /* Internal representation of either bound of a range (not what's on disk) */ |
60 | typedef struct |
61 | { |
62 | Datum val; /* the bound value, if any */ |
63 | bool infinite; /* bound is +/- infinity */ |
64 | bool inclusive; /* bound is inclusive (vs exclusive) */ |
65 | bool lower; /* this is the lower (vs upper) bound */ |
66 | } RangeBound; |
67 | |
68 | /* |
69 | * fmgr macros for range type objects |
70 | */ |
71 | #define DatumGetRangeTypeP(X) ((RangeType *) PG_DETOAST_DATUM(X)) |
72 | #define DatumGetRangeTypePCopy(X) ((RangeType *) PG_DETOAST_DATUM_COPY(X)) |
73 | #define RangeTypePGetDatum(X) PointerGetDatum(X) |
74 | #define PG_GETARG_RANGE_P(n) DatumGetRangeTypeP(PG_GETARG_DATUM(n)) |
75 | #define PG_GETARG_RANGE_P_COPY(n) DatumGetRangeTypePCopy(PG_GETARG_DATUM(n)) |
76 | #define PG_RETURN_RANGE_P(x) return RangeTypePGetDatum(x) |
77 | |
78 | /* Operator strategy numbers used in the GiST and SP-GiST range opclasses */ |
79 | /* Numbers are chosen to match up operator names with existing usages */ |
80 | #define RANGESTRAT_BEFORE RTLeftStrategyNumber |
81 | #define RANGESTRAT_OVERLEFT RTOverLeftStrategyNumber |
82 | #define RANGESTRAT_OVERLAPS RTOverlapStrategyNumber |
83 | #define RANGESTRAT_OVERRIGHT RTOverRightStrategyNumber |
84 | #define RANGESTRAT_AFTER RTRightStrategyNumber |
85 | #define RANGESTRAT_ADJACENT RTSameStrategyNumber |
86 | #define RANGESTRAT_CONTAINS RTContainsStrategyNumber |
87 | #define RANGESTRAT_CONTAINED_BY RTContainedByStrategyNumber |
88 | #define RANGESTRAT_CONTAINS_ELEM RTContainsElemStrategyNumber |
89 | #define RANGESTRAT_EQ RTEqualStrategyNumber |
90 | |
91 | /* |
92 | * prototypes for functions defined in rangetypes.c |
93 | */ |
94 | |
95 | extern bool range_contains_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val); |
96 | |
97 | /* internal versions of the above */ |
98 | extern bool range_eq_internal(TypeCacheEntry *typcache, RangeType *r1, |
99 | RangeType *r2); |
100 | extern bool range_ne_internal(TypeCacheEntry *typcache, RangeType *r1, |
101 | RangeType *r2); |
102 | extern bool range_contains_internal(TypeCacheEntry *typcache, RangeType *r1, |
103 | RangeType *r2); |
104 | extern bool range_contained_by_internal(TypeCacheEntry *typcache, RangeType *r1, |
105 | RangeType *r2); |
106 | extern bool range_before_internal(TypeCacheEntry *typcache, RangeType *r1, |
107 | RangeType *r2); |
108 | extern bool range_after_internal(TypeCacheEntry *typcache, RangeType *r1, |
109 | RangeType *r2); |
110 | extern bool range_adjacent_internal(TypeCacheEntry *typcache, RangeType *r1, |
111 | RangeType *r2); |
112 | extern bool range_overlaps_internal(TypeCacheEntry *typcache, RangeType *r1, |
113 | RangeType *r2); |
114 | extern bool range_overleft_internal(TypeCacheEntry *typcache, RangeType *r1, |
115 | RangeType *r2); |
116 | extern bool range_overright_internal(TypeCacheEntry *typcache, RangeType *r1, |
117 | RangeType *r2); |
118 | |
119 | /* assorted support functions */ |
120 | extern TypeCacheEntry *range_get_typcache(FunctionCallInfo fcinfo, |
121 | Oid rngtypid); |
122 | extern RangeType *range_serialize(TypeCacheEntry *typcache, RangeBound *lower, |
123 | RangeBound *upper, bool empty); |
124 | extern void range_deserialize(TypeCacheEntry *typcache, RangeType *range, |
125 | RangeBound *lower, RangeBound *upper, |
126 | bool *empty); |
127 | extern char range_get_flags(RangeType *range); |
128 | extern void range_set_contain_empty(RangeType *range); |
129 | extern RangeType *make_range(TypeCacheEntry *typcache, RangeBound *lower, |
130 | RangeBound *upper, bool empty); |
131 | extern int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, |
132 | RangeBound *b2); |
133 | extern int range_cmp_bound_values(TypeCacheEntry *typcache, RangeBound *b1, |
134 | RangeBound *b2); |
135 | extern bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound bound1, |
136 | RangeBound bound2); |
137 | extern RangeType *make_empty_range(TypeCacheEntry *typcache); |
138 | |
139 | #endif /* RANGETYPES_H */ |
140 | |