1 /*------------------------------------------------------------------------- 2 * 3 * rangetypes.h 4 * Declarations for Postgres range types. 5 * 6 * 7 * Portions Copyright (c) 1996-2021, 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 macros for range type objects 72 */ 73 #define DatumGetRangeTypeP(X) ((RangeType *) PG_DETOAST_DATUM(X)) 74 #define DatumGetRangeTypePCopy(X) ((RangeType *) PG_DETOAST_DATUM_COPY(X)) 75 #define RangeTypePGetDatum(X) PointerGetDatum(X) 76 #define PG_GETARG_RANGE_P(n) DatumGetRangeTypeP(PG_GETARG_DATUM(n)) 77 #define PG_GETARG_RANGE_P_COPY(n) DatumGetRangeTypePCopy(PG_GETARG_DATUM(n)) 78 #define PG_RETURN_RANGE_P(x) return RangeTypePGetDatum(x) 79 80 /* Operator strategy numbers used in the GiST and SP-GiST range opclasses */ 81 /* Numbers are chosen to match up operator names with existing usages */ 82 #define RANGESTRAT_BEFORE RTLeftStrategyNumber 83 #define RANGESTRAT_OVERLEFT RTOverLeftStrategyNumber 84 #define RANGESTRAT_OVERLAPS RTOverlapStrategyNumber 85 #define RANGESTRAT_OVERRIGHT RTOverRightStrategyNumber 86 #define RANGESTRAT_AFTER RTRightStrategyNumber 87 #define RANGESTRAT_ADJACENT RTSameStrategyNumber 88 #define RANGESTRAT_CONTAINS RTContainsStrategyNumber 89 #define RANGESTRAT_CONTAINED_BY RTContainedByStrategyNumber 90 #define RANGESTRAT_CONTAINS_ELEM RTContainsElemStrategyNumber 91 #define RANGESTRAT_EQ RTEqualStrategyNumber 92 93 /* 94 * prototypes for functions defined in rangetypes.c 95 */ 96 97 extern bool range_contains_elem_internal(TypeCacheEntry *typcache, const RangeType *r, Datum val); 98 99 /* internal versions of the above */ 100 extern bool range_eq_internal(TypeCacheEntry *typcache, const RangeType *r1, 101 const RangeType *r2); 102 extern bool range_ne_internal(TypeCacheEntry *typcache, const RangeType *r1, 103 const RangeType *r2); 104 extern bool range_contains_internal(TypeCacheEntry *typcache, const RangeType *r1, 105 const RangeType *r2); 106 extern bool range_contained_by_internal(TypeCacheEntry *typcache, const RangeType *r1, 107 const RangeType *r2); 108 extern bool range_before_internal(TypeCacheEntry *typcache, const RangeType *r1, 109 const RangeType *r2); 110 extern bool range_after_internal(TypeCacheEntry *typcache, const RangeType *r1, 111 const RangeType *r2); 112 extern bool range_adjacent_internal(TypeCacheEntry *typcache, const RangeType *r1, 113 const RangeType *r2); 114 extern bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1, 115 const RangeType *r2); 116 extern bool range_overleft_internal(TypeCacheEntry *typcache, const RangeType *r1, 117 const RangeType *r2); 118 extern bool range_overright_internal(TypeCacheEntry *typcache, const RangeType *r1, 119 const RangeType *r2); 120 extern RangeType *range_union_internal(TypeCacheEntry *typcache, RangeType *r1, 121 RangeType *r2, bool strict); 122 extern RangeType *range_minus_internal(TypeCacheEntry *typcache, RangeType *r1, 123 RangeType *r2); 124 extern RangeType *range_intersect_internal(TypeCacheEntry *typcache, const RangeType *r1, 125 const RangeType *r2); 126 127 /* assorted support functions */ 128 extern TypeCacheEntry *range_get_typcache(FunctionCallInfo fcinfo, 129 Oid rngtypid); 130 extern RangeType *range_serialize(TypeCacheEntry *typcache, RangeBound *lower, 131 RangeBound *upper, bool empty); 132 extern void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, 133 RangeBound *lower, RangeBound *upper, 134 bool *empty); 135 extern char range_get_flags(const RangeType *range); 136 extern void range_set_contain_empty(RangeType *range); 137 extern RangeType *make_range(TypeCacheEntry *typcache, RangeBound *lower, 138 RangeBound *upper, bool empty); 139 extern int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, 140 const RangeBound *b2); 141 extern int range_cmp_bound_values(TypeCacheEntry *typcache, const RangeBound *b1, 142 const RangeBound *b2); 143 extern int range_compare(const void *key1, const void *key2, void *arg); 144 extern bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound bound1, 145 RangeBound bound2); 146 extern RangeType *make_empty_range(TypeCacheEntry *typcache); 147 extern bool range_split_internal(TypeCacheEntry *typcache, const RangeType *r1, 148 const RangeType *r2, RangeType **output1, 149 RangeType **output2); 150 151 #endif /* RANGETYPES_H */ 152