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 */
25typedef 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) */
60typedef 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
95extern bool range_contains_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val);
96
97/* internal versions of the above */
98extern bool range_eq_internal(TypeCacheEntry *typcache, RangeType *r1,
99 RangeType *r2);
100extern bool range_ne_internal(TypeCacheEntry *typcache, RangeType *r1,
101 RangeType *r2);
102extern bool range_contains_internal(TypeCacheEntry *typcache, RangeType *r1,
103 RangeType *r2);
104extern bool range_contained_by_internal(TypeCacheEntry *typcache, RangeType *r1,
105 RangeType *r2);
106extern bool range_before_internal(TypeCacheEntry *typcache, RangeType *r1,
107 RangeType *r2);
108extern bool range_after_internal(TypeCacheEntry *typcache, RangeType *r1,
109 RangeType *r2);
110extern bool range_adjacent_internal(TypeCacheEntry *typcache, RangeType *r1,
111 RangeType *r2);
112extern bool range_overlaps_internal(TypeCacheEntry *typcache, RangeType *r1,
113 RangeType *r2);
114extern bool range_overleft_internal(TypeCacheEntry *typcache, RangeType *r1,
115 RangeType *r2);
116extern bool range_overright_internal(TypeCacheEntry *typcache, RangeType *r1,
117 RangeType *r2);
118
119/* assorted support functions */
120extern TypeCacheEntry *range_get_typcache(FunctionCallInfo fcinfo,
121 Oid rngtypid);
122extern RangeType *range_serialize(TypeCacheEntry *typcache, RangeBound *lower,
123 RangeBound *upper, bool empty);
124extern void range_deserialize(TypeCacheEntry *typcache, RangeType *range,
125 RangeBound *lower, RangeBound *upper,
126 bool *empty);
127extern char range_get_flags(RangeType *range);
128extern void range_set_contain_empty(RangeType *range);
129extern RangeType *make_range(TypeCacheEntry *typcache, RangeBound *lower,
130 RangeBound *upper, bool empty);
131extern int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1,
132 RangeBound *b2);
133extern int range_cmp_bound_values(TypeCacheEntry *typcache, RangeBound *b1,
134 RangeBound *b2);
135extern bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound bound1,
136 RangeBound bound2);
137extern RangeType *make_empty_range(TypeCacheEntry *typcache);
138
139#endif /* RANGETYPES_H */
140