1 /*-------------------------------------------------------------------------
2  *
3  * multirangetypes.h
4  *	  Declarations for Postgres multirange 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/multirangetypes.h
11  *
12  *-------------------------------------------------------------------------
13  */
14 #ifndef MULTIRANGETYPES_H
15 #define MULTIRANGETYPES_H
16 
17 #include "utils/rangetypes.h"
18 #include "utils/typcache.h"
19 
20 
21 /*
22  * Multiranges are varlena objects, so must meet the varlena convention that
23  * the first int32 of the object contains the total object size in bytes.
24  * Be sure to use VARSIZE() and SET_VARSIZE() to access it, though!
25  */
26 typedef struct
27 {
28 	int32		vl_len_;		/* varlena header (do not touch directly!) */
29 	Oid			multirangetypid;	/* multirange type's own OID */
30 	uint32		rangeCount;		/* the number of ranges */
31 
32 	/*
33 	 * Following the count are the range objects themselves, as ShortRangeType
34 	 * structs. Note that ranges are varlena too, depending on whether they
35 	 * have lower/upper bounds and because even their base types can be
36 	 * varlena. So we can't really index into this list.
37 	 */
38 } MultirangeType;
39 
40 /* Use these macros in preference to accessing these fields directly */
41 #define MultirangeTypeGetOid(mr)	((mr)->multirangetypid)
42 #define MultirangeIsEmpty(mr)  ((mr)->rangeCount == 0)
43 
44 /*
45  * fmgr macros for multirange type objects
46  */
47 #define DatumGetMultirangeTypeP(X)		((MultirangeType *) PG_DETOAST_DATUM(X))
48 #define DatumGetMultirangeTypePCopy(X)	((MultirangeType *) PG_DETOAST_DATUM_COPY(X))
49 #define MultirangeTypePGetDatum(X)		PointerGetDatum(X)
50 #define PG_GETARG_MULTIRANGE_P(n)		DatumGetMultirangeTypeP(PG_GETARG_DATUM(n))
51 #define PG_GETARG_MULTIRANGE_P_COPY(n)	DatumGetMultirangeTypePCopy(PG_GETARG_DATUM(n))
52 #define PG_RETURN_MULTIRANGE_P(x)		return MultirangeTypePGetDatum(x)
53 
54 /*
55  * prototypes for functions defined in multirangetypes.c
56  */
57 
58 /* internal versions of the above */
59 extern bool multirange_eq_internal(TypeCacheEntry *rangetyp,
60 								   const MultirangeType *mr1,
61 								   const MultirangeType *mr2);
62 extern bool multirange_ne_internal(TypeCacheEntry *rangetyp,
63 								   const MultirangeType *mr1,
64 								   const MultirangeType *mr2);
65 extern bool multirange_contains_elem_internal(TypeCacheEntry *rangetyp,
66 											  const MultirangeType *mr,
67 											  Datum elem);
68 extern bool multirange_contains_range_internal(TypeCacheEntry *rangetyp,
69 											   const MultirangeType *mr,
70 											   const RangeType *r);
71 extern bool range_contains_multirange_internal(TypeCacheEntry *rangetyp,
72 											   const RangeType *r,
73 											   const MultirangeType *mr);
74 extern bool multirange_contains_multirange_internal(TypeCacheEntry *rangetyp,
75 													const MultirangeType *mr1,
76 													const MultirangeType *mr2);
77 extern bool range_overlaps_multirange_internal(TypeCacheEntry *rangetyp,
78 											   const RangeType *r,
79 											   const MultirangeType *mr);
80 extern bool multirange_overlaps_multirange_internal(TypeCacheEntry *rangetyp,
81 													const MultirangeType *mr1,
82 													const MultirangeType *mr2);
83 extern bool range_overleft_multirange_internal(TypeCacheEntry *rangetyp,
84 											   const RangeType *r,
85 											   const MultirangeType *mr);
86 extern bool range_overright_multirange_internal(TypeCacheEntry *rangetyp,
87 												const RangeType *r,
88 												const MultirangeType *mr);
89 extern bool range_before_multirange_internal(TypeCacheEntry *rangetyp,
90 											 const RangeType *r,
91 											 const MultirangeType *mr);
92 extern bool range_after_multirange_internal(TypeCacheEntry *rangetyp,
93 											const RangeType *r,
94 											const MultirangeType *mr);
95 extern bool range_adjacent_multirange_internal(TypeCacheEntry *rangetyp,
96 											   const RangeType *r,
97 											   const MultirangeType *mr);
98 extern bool multirange_before_multirange_internal(TypeCacheEntry *rangetyp,
99 												  const MultirangeType *mr1,
100 												  const MultirangeType *mr2);
101 extern MultirangeType *multirange_minus_internal(Oid mltrngtypoid,
102 												 TypeCacheEntry *rangetyp,
103 												 int32 range_count1,
104 												 RangeType **ranges1,
105 												 int32 range_count2,
106 												 RangeType **ranges2);
107 extern MultirangeType *multirange_intersect_internal(Oid mltrngtypoid,
108 													 TypeCacheEntry *rangetyp,
109 													 int32 range_count1,
110 													 RangeType **ranges1,
111 													 int32 range_count2,
112 													 RangeType **ranges2);
113 
114 /* assorted support functions */
115 extern TypeCacheEntry *multirange_get_typcache(FunctionCallInfo fcinfo,
116 											   Oid mltrngtypid);
117 extern void multirange_deserialize(TypeCacheEntry *rangetyp,
118 								   const MultirangeType *range,
119 								   int32 *range_count,
120 								   RangeType ***ranges);
121 extern MultirangeType *make_multirange(Oid mltrngtypoid,
122 									   TypeCacheEntry *typcache,
123 									   int32 range_count, RangeType **ranges);
124 extern MultirangeType *make_empty_multirange(Oid mltrngtypoid,
125 											 TypeCacheEntry *rangetyp);
126 extern void multirange_get_bounds(TypeCacheEntry *rangetyp,
127 								  const MultirangeType *multirange,
128 								  uint32 i,
129 								  RangeBound *lower, RangeBound *upper);
130 extern RangeType *multirange_get_range(TypeCacheEntry *rangetyp,
131 									   const MultirangeType *multirange, int i);
132 extern RangeType *multirange_get_union_range(TypeCacheEntry *rangetyp,
133 											 const MultirangeType *mr);
134 
135 #endif							/* MULTIRANGETYPES_H */
136