2 * contrib/btree_gist/btree_time.c
6 #include "btree_gist.h"
7 #include "btree_utils_num.h"
8 #include "utils/fmgrprotos.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 fabs(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
;
219 PG_RETURN_BOOL(gbt_num_consistent(&key
, (void *) &query
, &strategy
,
220 GIST_LEAF(entry
), &tinfo
, fcinfo
->flinfo
));
224 gbt_time_distance(PG_FUNCTION_ARGS
)
226 GISTENTRY
*entry
= (GISTENTRY
*) PG_GETARG_POINTER(0);
227 TimeADT query
= PG_GETARG_TIMEADT(1);
229 /* Oid subtype = PG_GETARG_OID(3); */
230 timeKEY
*kkk
= (timeKEY
*) DatumGetPointer(entry
->key
);
233 key
.lower
= (GBT_NUMKEY
*) &kkk
->lower
;
234 key
.upper
= (GBT_NUMKEY
*) &kkk
->upper
;
236 PG_RETURN_FLOAT8(gbt_num_distance(&key
, (void *) &query
, GIST_LEAF(entry
),
237 &tinfo
, fcinfo
->flinfo
));
241 gbt_timetz_consistent(PG_FUNCTION_ARGS
)
243 GISTENTRY
*entry
= (GISTENTRY
*) PG_GETARG_POINTER(0);
244 TimeTzADT
*query
= PG_GETARG_TIMETZADT_P(1);
245 StrategyNumber strategy
= (StrategyNumber
) PG_GETARG_UINT16(2);
247 /* Oid subtype = PG_GETARG_OID(3); */
248 bool *recheck
= (bool *) PG_GETARG_POINTER(4);
249 timeKEY
*kkk
= (timeKEY
*) DatumGetPointer(entry
->key
);
253 /* All cases served by this function are inexact */
256 qqq
= query
->time
+ (query
->zone
* INT64CONST(1000000));
258 key
.lower
= (GBT_NUMKEY
*) &kkk
->lower
;
259 key
.upper
= (GBT_NUMKEY
*) &kkk
->upper
;
261 PG_RETURN_BOOL(gbt_num_consistent(&key
, (void *) &qqq
, &strategy
,
262 GIST_LEAF(entry
), &tinfo
, fcinfo
->flinfo
));
267 gbt_time_union(PG_FUNCTION_ARGS
)
269 GistEntryVector
*entryvec
= (GistEntryVector
*) PG_GETARG_POINTER(0);
270 void *out
= palloc(sizeof(timeKEY
));
272 *(int *) PG_GETARG_POINTER(1) = sizeof(timeKEY
);
273 PG_RETURN_POINTER(gbt_num_union((void *) out
, entryvec
, &tinfo
, fcinfo
->flinfo
));
278 gbt_time_penalty(PG_FUNCTION_ARGS
)
280 timeKEY
*origentry
= (timeKEY
*) DatumGetPointer(((GISTENTRY
*) PG_GETARG_POINTER(0))->key
);
281 timeKEY
*newentry
= (timeKEY
*) DatumGetPointer(((GISTENTRY
*) PG_GETARG_POINTER(1))->key
);
282 float *result
= (float *) PG_GETARG_POINTER(2);
287 intr
= DatumGetIntervalP(DirectFunctionCall2(time_mi_time
,
288 TimeADTGetDatumFast(newentry
->upper
),
289 TimeADTGetDatumFast(origentry
->upper
)));
290 res
= INTERVAL_TO_SEC(intr
);
293 intr
= DatumGetIntervalP(DirectFunctionCall2(time_mi_time
,
294 TimeADTGetDatumFast(origentry
->lower
),
295 TimeADTGetDatumFast(newentry
->lower
)));
296 res2
= INTERVAL_TO_SEC(intr
);
305 intr
= DatumGetIntervalP(DirectFunctionCall2(time_mi_time
,
306 TimeADTGetDatumFast(origentry
->upper
),
307 TimeADTGetDatumFast(origentry
->lower
)));
309 *result
+= (float) (res
/ (res
+ INTERVAL_TO_SEC(intr
)));
310 *result
*= (FLT_MAX
/ (((GISTENTRY
*) PG_GETARG_POINTER(0))->rel
->rd_att
->natts
+ 1));
313 PG_RETURN_POINTER(result
);
318 gbt_time_picksplit(PG_FUNCTION_ARGS
)
320 PG_RETURN_POINTER(gbt_num_picksplit((GistEntryVector
*) PG_GETARG_POINTER(0),
321 (GIST_SPLITVEC
*) PG_GETARG_POINTER(1),
322 &tinfo
, fcinfo
->flinfo
));
326 gbt_time_same(PG_FUNCTION_ARGS
)
328 timeKEY
*b1
= (timeKEY
*) PG_GETARG_POINTER(0);
329 timeKEY
*b2
= (timeKEY
*) PG_GETARG_POINTER(1);
330 bool *result
= (bool *) PG_GETARG_POINTER(2);
332 *result
= gbt_num_same((void *) b1
, (void *) b2
, &tinfo
, fcinfo
->flinfo
);
333 PG_RETURN_POINTER(result
);