2 * contrib/btree_gist/btree_time.c
6 #include "btree_gist.h"
7 #include "btree_utils_num.h"
8 #include "utils/builtins.h"
9 #include "utils/date.h"
10 #include "utils/timestamp.h"
21 PG_FUNCTION_INFO_V1(gbt_time_compress);
22 PG_FUNCTION_INFO_V1(gbt_timetz_compress);
23 PG_FUNCTION_INFO_V1(gbt_time_fetch);
24 PG_FUNCTION_INFO_V1(gbt_time_union);
25 PG_FUNCTION_INFO_V1(gbt_time_picksplit);
26 PG_FUNCTION_INFO_V1(gbt_time_consistent);
27 PG_FUNCTION_INFO_V1(gbt_time_distance);
28 PG_FUNCTION_INFO_V1(gbt_timetz_consistent);
29 PG_FUNCTION_INFO_V1(gbt_time_penalty);
30 PG_FUNCTION_INFO_V1(gbt_time_same);
33 #ifdef USE_FLOAT8_BYVAL
34 #define TimeADTGetDatumFast(X) TimeADTGetDatum(X)
36 #define TimeADTGetDatumFast(X) PointerGetDatum(&(X))
41 gbt_timegt(const void *a, const void *b, FmgrInfo *flinfo)
43 const TimeADT *aa = (const TimeADT *) a;
44 const TimeADT *bb = (const TimeADT *) b;
46 return DatumGetBool(DirectFunctionCall2(time_gt,
47 TimeADTGetDatumFast(*aa),
48 TimeADTGetDatumFast(*bb)));
52 gbt_timege(const void *a, const void *b, FmgrInfo *flinfo)
54 const TimeADT *aa = (const TimeADT *) a;
55 const TimeADT *bb = (const TimeADT *) b;
57 return DatumGetBool(DirectFunctionCall2(time_ge,
58 TimeADTGetDatumFast(*aa),
59 TimeADTGetDatumFast(*bb)));
63 gbt_timeeq(const void *a, const void *b, FmgrInfo *flinfo)
65 const TimeADT *aa = (const TimeADT *) a;
66 const TimeADT *bb = (const TimeADT *) b;
68 return DatumGetBool(DirectFunctionCall2(time_eq,
69 TimeADTGetDatumFast(*aa),
70 TimeADTGetDatumFast(*bb)));
74 gbt_timele(const void *a, const void *b, FmgrInfo *flinfo)
76 const TimeADT *aa = (const TimeADT *) a;
77 const TimeADT *bb = (const TimeADT *) b;
79 return DatumGetBool(DirectFunctionCall2(time_le,
80 TimeADTGetDatumFast(*aa),
81 TimeADTGetDatumFast(*bb)));
85 gbt_timelt(const void *a, const void *b, FmgrInfo *flinfo)
87 const TimeADT *aa = (const TimeADT *) a;
88 const TimeADT *bb = (const TimeADT *) b;
90 return DatumGetBool(DirectFunctionCall2(time_lt,
91 TimeADTGetDatumFast(*aa),
92 TimeADTGetDatumFast(*bb)));
98 gbt_timekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
100 timeKEY *ia = (timeKEY *) (((const Nsrt *) a)->t);
101 timeKEY *ib = (timeKEY *) (((const Nsrt *) b)->t);
104 res = DatumGetInt32(DirectFunctionCall2(time_cmp, TimeADTGetDatumFast(ia->lower), TimeADTGetDatumFast(ib->lower)));
106 return DatumGetInt32(DirectFunctionCall2(time_cmp, TimeADTGetDatumFast(ia->upper), TimeADTGetDatumFast(ib->upper)));
112 gbt_time_dist(const void *a, const void *b, FmgrInfo *flinfo)
114 const TimeADT *aa = (const TimeADT *) a;
115 const TimeADT *bb = (const TimeADT *) b;
118 i = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
119 TimeADTGetDatumFast(*aa),
120 TimeADTGetDatumFast(*bb)));
121 return (float8) Abs(INTERVAL_TO_SEC(i));
125 static const gbtree_ninfo tinfo =
129 16, /* sizeof(gbtreekey16) */
140 PG_FUNCTION_INFO_V1(time_dist);
142 time_dist(PG_FUNCTION_ARGS)
144 Datum diff = DirectFunctionCall2(time_mi_time,
148 PG_RETURN_INTERVAL_P(abs_interval(DatumGetIntervalP(diff)));
152 /**************************************************
154 **************************************************/
159 gbt_time_compress(PG_FUNCTION_ARGS)
161 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
163 PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
168 gbt_timetz_compress(PG_FUNCTION_ARGS)
170 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
175 timeKEY *r = (timeKEY *) palloc(sizeof(timeKEY));
176 TimeTzADT *tz = DatumGetTimeTzADTP(entry->key);
179 retval = palloc(sizeof(GISTENTRY));
181 /* We are using the time + zone only to compress */
182 tmp = tz->time + (tz->zone * INT64CONST(1000000));
183 r->lower = r->upper = tmp;
184 gistentryinit(*retval, PointerGetDatum(r),
185 entry->rel, entry->page,
186 entry->offset, false);
190 PG_RETURN_POINTER(retval);
194 gbt_time_fetch(PG_FUNCTION_ARGS)
196 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
198 PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
202 gbt_time_consistent(PG_FUNCTION_ARGS)
204 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
205 TimeADT query = PG_GETARG_TIMEADT(1);
206 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
208 /* Oid subtype = PG_GETARG_OID(3); */
209 bool *recheck = (bool *) PG_GETARG_POINTER(4);
210 timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
213 /* All cases served by this function are exact */
216 key.lower = (GBT_NUMKEY *) &kkk->lower;
217 key.upper = (GBT_NUMKEY *) &kkk->upper;
220 gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
225 gbt_time_distance(PG_FUNCTION_ARGS)
227 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
228 TimeADT query = PG_GETARG_TIMEADT(1);
230 /* Oid subtype = PG_GETARG_OID(3); */
231 timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
234 key.lower = (GBT_NUMKEY *) &kkk->lower;
235 key.upper = (GBT_NUMKEY *) &kkk->upper;
238 gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
243 gbt_timetz_consistent(PG_FUNCTION_ARGS)
245 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
246 TimeTzADT *query = PG_GETARG_TIMETZADT_P(1);
247 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
249 /* Oid subtype = PG_GETARG_OID(3); */
250 bool *recheck = (bool *) PG_GETARG_POINTER(4);
251 timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
255 /* All cases served by this function are inexact */
258 qqq = query->time + (query->zone * INT64CONST(1000000));
260 key.lower = (GBT_NUMKEY *) &kkk->lower;
261 key.upper = (GBT_NUMKEY *) &kkk->upper;
264 gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
270 gbt_time_union(PG_FUNCTION_ARGS)
272 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
273 void *out = palloc(sizeof(timeKEY));
275 *(int *) PG_GETARG_POINTER(1) = sizeof(timeKEY);
276 PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
281 gbt_time_penalty(PG_FUNCTION_ARGS)
283 timeKEY *origentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
284 timeKEY *newentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
285 float *result = (float *) PG_GETARG_POINTER(2);
290 intr = DatumGetIntervalP(DirectFunctionCall2(
292 TimeADTGetDatumFast(newentry->upper),
293 TimeADTGetDatumFast(origentry->upper)));
294 res = INTERVAL_TO_SEC(intr);
297 intr = DatumGetIntervalP(DirectFunctionCall2(
299 TimeADTGetDatumFast(origentry->lower),
300 TimeADTGetDatumFast(newentry->lower)));
301 res2 = INTERVAL_TO_SEC(intr);
310 intr = DatumGetIntervalP(DirectFunctionCall2(
312 TimeADTGetDatumFast(origentry->upper),
313 TimeADTGetDatumFast(origentry->lower)));
315 *result += (float) (res / (res + INTERVAL_TO_SEC(intr)));
316 *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
319 PG_RETURN_POINTER(result);
324 gbt_time_picksplit(PG_FUNCTION_ARGS)
326 PG_RETURN_POINTER(gbt_num_picksplit(
327 (GistEntryVector *) PG_GETARG_POINTER(0),
328 (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
329 &tinfo, fcinfo->flinfo
334 gbt_time_same(PG_FUNCTION_ARGS)
336 timeKEY *b1 = (timeKEY *) PG_GETARG_POINTER(0);
337 timeKEY *b2 = (timeKEY *) PG_GETARG_POINTER(1);
338 bool *result = (bool *) PG_GETARG_POINTER(2);
340 *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
341 PG_RETURN_POINTER(result);