Only skip pages marked as clean in the visibility map, if the last 32
[PostgreSQL.git] / contrib / btree_gist / btree_ts.c
blob04d9e184af430a123b30c934eb4f36a372a0cd4f
1 /*
2 * $PostgreSQL:$
3 */
4 #include "btree_gist.h"
5 #include "btree_utils_num.h"
6 #include "utils/datetime.h"
8 typedef struct
10 Timestamp lower;
11 Timestamp upper;
12 } tsKEY;
15 ** timestamp ops
17 PG_FUNCTION_INFO_V1(gbt_ts_compress);
18 PG_FUNCTION_INFO_V1(gbt_tstz_compress);
19 PG_FUNCTION_INFO_V1(gbt_ts_union);
20 PG_FUNCTION_INFO_V1(gbt_ts_picksplit);
21 PG_FUNCTION_INFO_V1(gbt_ts_consistent);
22 PG_FUNCTION_INFO_V1(gbt_tstz_consistent);
23 PG_FUNCTION_INFO_V1(gbt_ts_penalty);
24 PG_FUNCTION_INFO_V1(gbt_ts_same);
26 Datum gbt_ts_compress(PG_FUNCTION_ARGS);
27 Datum gbt_tstz_compress(PG_FUNCTION_ARGS);
28 Datum gbt_ts_union(PG_FUNCTION_ARGS);
29 Datum gbt_ts_picksplit(PG_FUNCTION_ARGS);
30 Datum gbt_ts_consistent(PG_FUNCTION_ARGS);
31 Datum gbt_tstz_consistent(PG_FUNCTION_ARGS);
32 Datum gbt_ts_penalty(PG_FUNCTION_ARGS);
33 Datum gbt_ts_same(PG_FUNCTION_ARGS);
36 #ifdef USE_FLOAT8_BYVAL
37 #define TimestampGetDatumFast(X) TimestampGetDatum(X)
38 #else
39 #define TimestampGetDatumFast(X) PointerGetDatum(&(X))
40 #endif
43 static bool
44 gbt_tsgt(const void *a, const void *b)
46 const Timestamp *aa = (const Timestamp *) a;
47 const Timestamp *bb = (const Timestamp *) b;
49 return DatumGetBool(DirectFunctionCall2(timestamp_gt,
50 TimestampGetDatumFast(*aa),
51 TimestampGetDatumFast(*bb)));
54 static bool
55 gbt_tsge(const void *a, const void *b)
57 const Timestamp *aa = (const Timestamp *) a;
58 const Timestamp *bb = (const Timestamp *) b;
60 return DatumGetBool(DirectFunctionCall2(timestamp_ge,
61 TimestampGetDatumFast(*aa),
62 TimestampGetDatumFast(*bb)));
65 static bool
66 gbt_tseq(const void *a, const void *b)
68 const Timestamp *aa = (const Timestamp *) a;
69 const Timestamp *bb = (const Timestamp *) b;
71 return DatumGetBool(DirectFunctionCall2(timestamp_eq,
72 TimestampGetDatumFast(*aa),
73 TimestampGetDatumFast(*bb)));
76 static bool
77 gbt_tsle(const void *a, const void *b)
79 const Timestamp *aa = (const Timestamp *) a;
80 const Timestamp *bb = (const Timestamp *) b;
82 return DatumGetBool(DirectFunctionCall2(timestamp_le,
83 TimestampGetDatumFast(*aa),
84 TimestampGetDatumFast(*bb)));
87 static bool
88 gbt_tslt(const void *a, const void *b)
90 const Timestamp *aa = (const Timestamp *) a;
91 const Timestamp *bb = (const Timestamp *) b;
93 return DatumGetBool(DirectFunctionCall2(timestamp_lt,
94 TimestampGetDatumFast(*aa),
95 TimestampGetDatumFast(*bb)));
99 static int
100 gbt_tskey_cmp(const void *a, const void *b)
102 if (gbt_tsgt((void *) &(((Nsrt *) a)->t[0]), (void *) &(((Nsrt *) b)->t[0])))
103 return 1;
104 else if (gbt_tslt((void *) &(((Nsrt *) a)->t[0]), (void *) &(((Nsrt *) b)->t[0])))
105 return -1;
106 return 0;
110 static const gbtree_ninfo tinfo =
112 gbt_t_ts,
113 sizeof(Timestamp),
114 gbt_tsgt,
115 gbt_tsge,
116 gbt_tseq,
117 gbt_tsle,
118 gbt_tslt,
119 gbt_tskey_cmp
123 /**************************************************
124 * timestamp ops
125 **************************************************/
128 static Timestamp
129 tstz_to_ts_gmt(TimestampTz ts)
131 Timestamp gmt;
132 int val,
135 gmt = ts;
136 DecodeSpecial(0, "gmt", &val);
138 if (ts < DT_NOEND && ts > DT_NOBEGIN)
140 tz = val * 60;
142 #ifdef HAVE_INT64_TIMESTAMP
143 gmt -= (tz * INT64CONST(1000000));
144 #else
145 gmt -= tz;
146 #endif
148 return gmt;
152 Datum
153 gbt_ts_compress(PG_FUNCTION_ARGS)
155 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
156 GISTENTRY *retval = NULL;
158 PG_RETURN_POINTER(gbt_num_compress(retval, entry, &tinfo));
162 Datum
163 gbt_tstz_compress(PG_FUNCTION_ARGS)
165 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
166 GISTENTRY *retval;
168 if (entry->leafkey)
170 tsKEY *r = (tsKEY *) palloc(sizeof(tsKEY));
171 TimestampTz ts = DatumGetTimestampTz(entry->key);
172 Timestamp gmt;
174 gmt = tstz_to_ts_gmt(ts);
176 retval = palloc(sizeof(GISTENTRY));
177 r->lower = r->upper = gmt;
178 gistentryinit(*retval, PointerGetDatum(r),
179 entry->rel, entry->page,
180 entry->offset, FALSE);
182 else
183 retval = entry;
185 PG_RETURN_POINTER(retval);
189 Datum
190 gbt_ts_consistent(PG_FUNCTION_ARGS)
192 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
193 Timestamp query = PG_GETARG_TIMESTAMP(1);
194 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
195 /* Oid subtype = PG_GETARG_OID(3); */
196 bool *recheck = (bool *) PG_GETARG_POINTER(4);
197 tsKEY *kkk = (tsKEY *) DatumGetPointer(entry->key);
198 GBT_NUMKEY_R key;
200 /* All cases served by this function are exact */
201 *recheck = false;
203 key.lower = (GBT_NUMKEY *) & kkk->lower;
204 key.upper = (GBT_NUMKEY *) & kkk->upper;
206 PG_RETURN_BOOL(
207 gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
211 Datum
212 gbt_tstz_consistent(PG_FUNCTION_ARGS)
214 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
215 TimestampTz query = PG_GETARG_TIMESTAMPTZ(1);
216 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
217 /* Oid subtype = PG_GETARG_OID(3); */
218 bool *recheck = (bool *) PG_GETARG_POINTER(4);
219 char *kkk = (char *) DatumGetPointer(entry->key);
220 GBT_NUMKEY_R key;
221 Timestamp qqq;
223 /* All cases served by this function are exact */
224 *recheck = false;
226 key.lower = (GBT_NUMKEY *) & kkk[0];
227 key.upper = (GBT_NUMKEY *) & kkk[MAXALIGN(tinfo.size)];
228 qqq = tstz_to_ts_gmt(query);
230 PG_RETURN_BOOL(
231 gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo)
236 Datum
237 gbt_ts_union(PG_FUNCTION_ARGS)
239 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
240 void *out = palloc(sizeof(tsKEY));
242 *(int *) PG_GETARG_POINTER(1) = sizeof(tsKEY);
243 PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
247 #define penalty_check_max_float(val) do { \
248 if ( val > FLT_MAX ) \
249 val = FLT_MAX; \
250 if ( val < -FLT_MAX ) \
251 val = -FLT_MAX; \
252 } while(false);
255 Datum
256 gbt_ts_penalty(PG_FUNCTION_ARGS)
259 tsKEY *origentry = (tsKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
260 tsKEY *newentry = (tsKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
261 float *result = (float *) PG_GETARG_POINTER(2);
263 double orgdbl[2],
264 newdbl[2];
267 * We are allways using "double" timestamps here. Precision should be good
268 * enough.
270 orgdbl[0] = ((double) origentry->lower);
271 orgdbl[1] = ((double) origentry->upper);
272 newdbl[0] = ((double) newentry->lower);
273 newdbl[1] = ((double) newentry->upper);
275 penalty_check_max_float(orgdbl[0]);
276 penalty_check_max_float(orgdbl[1]);
277 penalty_check_max_float(newdbl[0]);
278 penalty_check_max_float(newdbl[1]);
280 penalty_num(result, orgdbl[0], orgdbl[1], newdbl[0], newdbl[1]);
282 PG_RETURN_POINTER(result);
287 Datum
288 gbt_ts_picksplit(PG_FUNCTION_ARGS)
290 PG_RETURN_POINTER(gbt_num_picksplit(
291 (GistEntryVector *) PG_GETARG_POINTER(0),
292 (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
293 &tinfo
297 Datum
298 gbt_ts_same(PG_FUNCTION_ARGS)
300 tsKEY *b1 = (tsKEY *) PG_GETARG_POINTER(0);
301 tsKEY *b2 = (tsKEY *) PG_GETARG_POINTER(1);
302 bool *result = (bool *) PG_GETARG_POINTER(2);
304 *result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
305 PG_RETURN_POINTER(result);