Only skip pages marked as clean in the visibility map, if the last 32
[PostgreSQL.git] / contrib / btree_gist / btree_interval.c
blob5cad10f79067c9f63dbba4642aed60db683687ee
1 /*
2 * $PostgreSQL:$
3 */
4 #include "btree_gist.h"
5 #include "btree_utils_num.h"
6 #include "utils/timestamp.h"
8 typedef struct
10 Interval lower,
11 upper;
12 } intvKEY;
16 ** Interval ops
18 PG_FUNCTION_INFO_V1(gbt_intv_compress);
19 PG_FUNCTION_INFO_V1(gbt_intv_decompress);
20 PG_FUNCTION_INFO_V1(gbt_intv_union);
21 PG_FUNCTION_INFO_V1(gbt_intv_picksplit);
22 PG_FUNCTION_INFO_V1(gbt_intv_consistent);
23 PG_FUNCTION_INFO_V1(gbt_intv_penalty);
24 PG_FUNCTION_INFO_V1(gbt_intv_same);
26 Datum gbt_intv_compress(PG_FUNCTION_ARGS);
27 Datum gbt_intv_decompress(PG_FUNCTION_ARGS);
28 Datum gbt_intv_union(PG_FUNCTION_ARGS);
29 Datum gbt_intv_picksplit(PG_FUNCTION_ARGS);
30 Datum gbt_intv_consistent(PG_FUNCTION_ARGS);
31 Datum gbt_intv_penalty(PG_FUNCTION_ARGS);
32 Datum gbt_intv_same(PG_FUNCTION_ARGS);
35 static bool
36 gbt_intvgt(const void *a, const void *b)
38 return DatumGetBool(DirectFunctionCall2(interval_gt, IntervalPGetDatum(a), IntervalPGetDatum(b)));
41 static bool
42 gbt_intvge(const void *a, const void *b)
44 return DatumGetBool(DirectFunctionCall2(interval_ge, IntervalPGetDatum(a), IntervalPGetDatum(b)));
47 static bool
48 gbt_intveq(const void *a, const void *b)
50 return DatumGetBool(DirectFunctionCall2(interval_eq, IntervalPGetDatum(a), IntervalPGetDatum(b)));
53 static bool
54 gbt_intvle(const void *a, const void *b)
56 return DatumGetBool(DirectFunctionCall2(interval_le, IntervalPGetDatum(a), IntervalPGetDatum(b)));
59 static bool
60 gbt_intvlt(const void *a, const void *b)
62 return DatumGetBool(DirectFunctionCall2(interval_lt, IntervalPGetDatum(a), IntervalPGetDatum(b)));
65 static int
66 gbt_intvkey_cmp(const void *a, const void *b)
68 return DatumGetInt32(
69 DirectFunctionCall2(interval_cmp,
70 IntervalPGetDatum(((Nsrt *) a)->t),
71 IntervalPGetDatum(((Nsrt *) b)->t)
77 static double
78 intr2num(const Interval *i)
80 return INTERVAL_TO_SEC(i);
84 * INTERVALSIZE should be the actual size-on-disk of an Interval, as shown
85 * in pg_type. This might be less than sizeof(Interval) if the compiler
86 * insists on adding alignment padding at the end of the struct.
88 #define INTERVALSIZE 16
90 static const gbtree_ninfo tinfo =
92 gbt_t_intv,
93 sizeof(Interval),
94 gbt_intvgt,
95 gbt_intvge,
96 gbt_intveq,
97 gbt_intvle,
98 gbt_intvlt,
99 gbt_intvkey_cmp
103 /**************************************************
104 * interval ops
105 **************************************************/
108 Datum
109 gbt_intv_compress(PG_FUNCTION_ARGS)
111 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
112 GISTENTRY *retval = entry;
114 if (entry->leafkey || INTERVALSIZE != sizeof(Interval))
116 char *r = (char *) palloc(2 * INTERVALSIZE);
118 retval = palloc(sizeof(GISTENTRY));
120 if (entry->leafkey)
122 Interval *key = DatumGetIntervalP(entry->key);
124 memcpy((void *) r, (void *) key, INTERVALSIZE);
125 memcpy((void *) (r + INTERVALSIZE), (void *) key, INTERVALSIZE);
127 else
129 intvKEY *key = (intvKEY *) DatumGetPointer(entry->key);
131 memcpy(r, &key->lower, INTERVALSIZE);
132 memcpy(r + INTERVALSIZE, &key->upper, INTERVALSIZE);
134 gistentryinit(*retval, PointerGetDatum(r),
135 entry->rel, entry->page,
136 entry->offset, FALSE);
139 PG_RETURN_POINTER(retval);
143 Datum
144 gbt_intv_decompress(PG_FUNCTION_ARGS)
146 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
147 GISTENTRY *retval = entry;
149 if (INTERVALSIZE != sizeof(Interval))
151 intvKEY *r = palloc(sizeof(intvKEY));
152 char *key = DatumGetPointer(entry->key);
154 retval = palloc(sizeof(GISTENTRY));
155 memcpy(&r->lower, key, INTERVALSIZE);
156 memcpy(&r->upper, key + INTERVALSIZE, INTERVALSIZE);
158 gistentryinit(*retval, PointerGetDatum(r),
159 entry->rel, entry->page,
160 entry->offset, FALSE);
162 PG_RETURN_POINTER(retval);
166 Datum
167 gbt_intv_consistent(PG_FUNCTION_ARGS)
169 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
170 Interval *query = PG_GETARG_INTERVAL_P(1);
171 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
172 /* Oid subtype = PG_GETARG_OID(3); */
173 bool *recheck = (bool *) PG_GETARG_POINTER(4);
174 intvKEY *kkk = (intvKEY *) DatumGetPointer(entry->key);
175 GBT_NUMKEY_R key;
177 /* All cases served by this function are exact */
178 *recheck = false;
180 key.lower = (GBT_NUMKEY *) & kkk->lower;
181 key.upper = (GBT_NUMKEY *) & kkk->upper;
183 PG_RETURN_BOOL(
184 gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo)
189 Datum
190 gbt_intv_union(PG_FUNCTION_ARGS)
192 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
193 void *out = palloc(sizeof(intvKEY));
195 *(int *) PG_GETARG_POINTER(1) = sizeof(intvKEY);
196 PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
200 Datum
201 gbt_intv_penalty(PG_FUNCTION_ARGS)
203 intvKEY *origentry = (intvKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
204 intvKEY *newentry = (intvKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
205 float *result = (float *) PG_GETARG_POINTER(2);
206 double iorg[2],
207 inew[2];
209 iorg[0] = intr2num(&origentry->lower);
210 iorg[1] = intr2num(&origentry->upper);
211 inew[0] = intr2num(&newentry->lower);
212 inew[1] = intr2num(&newentry->upper);
214 penalty_num(result, iorg[0], iorg[1], inew[0], inew[1]);
216 PG_RETURN_POINTER(result);
220 Datum
221 gbt_intv_picksplit(PG_FUNCTION_ARGS)
223 PG_RETURN_POINTER(gbt_num_picksplit(
224 (GistEntryVector *) PG_GETARG_POINTER(0),
225 (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
226 &tinfo
230 Datum
231 gbt_intv_same(PG_FUNCTION_ARGS)
233 intvKEY *b1 = (intvKEY *) PG_GETARG_POINTER(0);
234 intvKEY *b2 = (intvKEY *) PG_GETARG_POINTER(1);
235 bool *result = (bool *) PG_GETARG_POINTER(2);
237 *result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
238 PG_RETURN_POINTER(result);