2 * contrib/btree_gist/btree_time.c
4 #include "btree_gist.h"
5 #include "btree_utils_num.h"
6 #include "utils/date.h"
7 #include "utils/timestamp.h"
18 PG_FUNCTION_INFO_V1(gbt_time_compress);
19 PG_FUNCTION_INFO_V1(gbt_timetz_compress);
20 PG_FUNCTION_INFO_V1(gbt_time_union);
21 PG_FUNCTION_INFO_V1(gbt_time_picksplit);
22 PG_FUNCTION_INFO_V1(gbt_time_consistent);
23 PG_FUNCTION_INFO_V1(gbt_time_distance);
24 PG_FUNCTION_INFO_V1(gbt_timetz_consistent);
25 PG_FUNCTION_INFO_V1(gbt_time_penalty);
26 PG_FUNCTION_INFO_V1(gbt_time_same);
28 Datum gbt_time_compress(PG_FUNCTION_ARGS);
29 Datum gbt_timetz_compress(PG_FUNCTION_ARGS);
30 Datum gbt_time_union(PG_FUNCTION_ARGS);
31 Datum gbt_time_picksplit(PG_FUNCTION_ARGS);
32 Datum gbt_time_consistent(PG_FUNCTION_ARGS);
33 Datum gbt_time_distance(PG_FUNCTION_ARGS);
34 Datum gbt_timetz_consistent(PG_FUNCTION_ARGS);
35 Datum gbt_time_penalty(PG_FUNCTION_ARGS);
36 Datum gbt_time_same(PG_FUNCTION_ARGS);
39 #ifdef USE_FLOAT8_BYVAL
40 #define TimeADTGetDatumFast(X) TimeADTGetDatum(X)
42 #define TimeADTGetDatumFast(X) PointerGetDatum(&(X))
47 gbt_timegt(const void *a, const void *b)
49 const TimeADT *aa = (const TimeADT *) a;
50 const TimeADT *bb = (const TimeADT *) b;
52 return DatumGetBool(DirectFunctionCall2(time_gt,
53 TimeADTGetDatumFast(*aa),
54 TimeADTGetDatumFast(*bb)));
58 gbt_timege(const void *a, const void *b)
60 const TimeADT *aa = (const TimeADT *) a;
61 const TimeADT *bb = (const TimeADT *) b;
63 return DatumGetBool(DirectFunctionCall2(time_ge,
64 TimeADTGetDatumFast(*aa),
65 TimeADTGetDatumFast(*bb)));
69 gbt_timeeq(const void *a, const void *b)
71 const TimeADT *aa = (const TimeADT *) a;
72 const TimeADT *bb = (const TimeADT *) b;
74 return DatumGetBool(DirectFunctionCall2(time_eq,
75 TimeADTGetDatumFast(*aa),
76 TimeADTGetDatumFast(*bb)));
80 gbt_timele(const void *a, const void *b)
82 const TimeADT *aa = (const TimeADT *) a;
83 const TimeADT *bb = (const TimeADT *) b;
85 return DatumGetBool(DirectFunctionCall2(time_le,
86 TimeADTGetDatumFast(*aa),
87 TimeADTGetDatumFast(*bb)));
91 gbt_timelt(const void *a, const void *b)
93 const TimeADT *aa = (const TimeADT *) a;
94 const TimeADT *bb = (const TimeADT *) b;
96 return DatumGetBool(DirectFunctionCall2(time_lt,
97 TimeADTGetDatumFast(*aa),
98 TimeADTGetDatumFast(*bb)));
104 gbt_timekey_cmp(const void *a, const void *b)
106 timeKEY *ia = (timeKEY *) (((Nsrt *) a)->t);
107 timeKEY *ib = (timeKEY *) (((Nsrt *) b)->t);
110 res = DatumGetInt32(DirectFunctionCall2(time_cmp, TimeADTGetDatumFast(ia->lower), TimeADTGetDatumFast(ib->lower)));
112 return DatumGetInt32(DirectFunctionCall2(time_cmp, TimeADTGetDatumFast(ia->upper), TimeADTGetDatumFast(ib->upper)));
118 gbt_time_dist(const void *a, const void *b)
120 const TimeADT *aa = (const TimeADT *) a;
121 const TimeADT *bb = (const TimeADT *) b;
124 i = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
125 TimeADTGetDatumFast(*aa),
126 TimeADTGetDatumFast(*bb)));
127 return (float8) Abs(INTERVAL_TO_SEC(i));
131 static const gbtree_ninfo tinfo =
145 PG_FUNCTION_INFO_V1(time_dist);
146 Datum time_dist(PG_FUNCTION_ARGS);
148 time_dist(PG_FUNCTION_ARGS)
150 Datum diff = DirectFunctionCall2(time_mi_time,
154 PG_RETURN_INTERVAL_P(abs_interval(DatumGetIntervalP(diff)));
158 /**************************************************
160 **************************************************/
165 gbt_time_compress(PG_FUNCTION_ARGS)
167 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
168 GISTENTRY *retval = NULL;
170 PG_RETURN_POINTER(gbt_num_compress(retval, entry, &tinfo));
175 gbt_timetz_compress(PG_FUNCTION_ARGS)
177 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
182 timeKEY *r = (timeKEY *) palloc(sizeof(timeKEY));
183 TimeTzADT *tz = DatumGetTimeTzADTP(entry->key);
186 retval = palloc(sizeof(GISTENTRY));
188 /* We are using the time + zone only to compress */
189 #ifdef HAVE_INT64_TIMESTAMP
190 tmp = tz->time + (tz->zone * INT64CONST(1000000));
192 tmp = (tz->time + tz->zone);
194 r->lower = r->upper = tmp;
195 gistentryinit(*retval, PointerGetDatum(r),
196 entry->rel, entry->page,
197 entry->offset, FALSE);
201 PG_RETURN_POINTER(retval);
206 gbt_time_consistent(PG_FUNCTION_ARGS)
208 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
209 TimeADT query = PG_GETARG_TIMEADT(1);
210 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
212 /* Oid subtype = PG_GETARG_OID(3); */
213 bool *recheck = (bool *) PG_GETARG_POINTER(4);
214 timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
217 /* All cases served by this function are exact */
220 key.lower = (GBT_NUMKEY *) &kkk->lower;
221 key.upper = (GBT_NUMKEY *) &kkk->upper;
224 gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
229 gbt_time_distance(PG_FUNCTION_ARGS)
231 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
232 TimeADT query = PG_GETARG_TIMEADT(1);
234 /* Oid subtype = PG_GETARG_OID(3); */
235 timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
238 key.lower = (GBT_NUMKEY *) &kkk->lower;
239 key.upper = (GBT_NUMKEY *) &kkk->upper;
242 gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
247 gbt_timetz_consistent(PG_FUNCTION_ARGS)
249 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
250 TimeTzADT *query = PG_GETARG_TIMETZADT_P(1);
251 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
253 /* Oid subtype = PG_GETARG_OID(3); */
254 bool *recheck = (bool *) PG_GETARG_POINTER(4);
255 timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
259 /* All cases served by this function are inexact */
262 #ifdef HAVE_INT64_TIMESTAMP
263 qqq = query->time + (query->zone * INT64CONST(1000000));
265 qqq = (query->time + query->zone);
268 key.lower = (GBT_NUMKEY *) &kkk->lower;
269 key.upper = (GBT_NUMKEY *) &kkk->upper;
272 gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo)
278 gbt_time_union(PG_FUNCTION_ARGS)
280 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
281 void *out = palloc(sizeof(timeKEY));
283 *(int *) PG_GETARG_POINTER(1) = sizeof(timeKEY);
284 PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
289 gbt_time_penalty(PG_FUNCTION_ARGS)
291 timeKEY *origentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
292 timeKEY *newentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
293 float *result = (float *) PG_GETARG_POINTER(2);
298 intr = DatumGetIntervalP(DirectFunctionCall2(
300 TimeADTGetDatumFast(newentry->upper),
301 TimeADTGetDatumFast(origentry->upper)));
302 res = INTERVAL_TO_SEC(intr);
305 intr = DatumGetIntervalP(DirectFunctionCall2(
307 TimeADTGetDatumFast(origentry->lower),
308 TimeADTGetDatumFast(newentry->lower)));
309 res2 = INTERVAL_TO_SEC(intr);
318 intr = DatumGetIntervalP(DirectFunctionCall2(
320 TimeADTGetDatumFast(origentry->upper),
321 TimeADTGetDatumFast(origentry->lower)));
323 *result += (float) (res / (res + INTERVAL_TO_SEC(intr)));
324 *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
327 PG_RETURN_POINTER(result);
332 gbt_time_picksplit(PG_FUNCTION_ARGS)
334 PG_RETURN_POINTER(gbt_num_picksplit(
335 (GistEntryVector *) PG_GETARG_POINTER(0),
336 (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
342 gbt_time_same(PG_FUNCTION_ARGS)
344 timeKEY *b1 = (timeKEY *) PG_GETARG_POINTER(0);
345 timeKEY *b2 = (timeKEY *) PG_GETARG_POINTER(1);
346 bool *result = (bool *) PG_GETARG_POINTER(2);
348 *result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
349 PG_RETURN_POINTER(result);