1 /*------------------------------------------------------------------------- 2 * 3 * rangetypes.h 4 * Declarations for Postgres range types. 5 * 6 * 7 * Portions Copyright (c) 1996-2017, 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 DatumGetRangeType(X) ((RangeType *) PG_DETOAST_DATUM(X)) 72 #define DatumGetRangeTypeCopy(X) ((RangeType *) PG_DETOAST_DATUM_COPY(X)) 73 #define RangeTypeGetDatum(X) PointerGetDatum(X) 74 #define PG_GETARG_RANGE(n) DatumGetRangeType(PG_GETARG_DATUM(n)) 75 #define PG_GETARG_RANGE_COPY(n) DatumGetRangeTypeCopy(PG_GETARG_DATUM(n)) 76 #define PG_RETURN_RANGE(x) return RangeTypeGetDatum(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