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