4 #include "btree_gist.h"
5 #include "btree_utils_num.h"
6 #include "utils/datetime.h"
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)
39 #define TimestampGetDatumFast(X) PointerGetDatum(&(X))
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
)));
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
)));
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
)));
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
)));
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
)));
100 gbt_tskey_cmp(const void *a
, const void *b
)
102 if (gbt_tsgt((void *) &(((Nsrt
*) a
)->t
[0]), (void *) &(((Nsrt
*) b
)->t
[0])))
104 else if (gbt_tslt((void *) &(((Nsrt
*) a
)->t
[0]), (void *) &(((Nsrt
*) b
)->t
[0])))
110 static const gbtree_ninfo tinfo
=
123 /**************************************************
125 **************************************************/
129 tstz_to_ts_gmt(TimestampTz ts
)
136 DecodeSpecial(0, "gmt", &val
);
138 if (ts
< DT_NOEND
&& ts
> DT_NOBEGIN
)
142 #ifdef HAVE_INT64_TIMESTAMP
143 gmt
-= (tz
* INT64CONST(1000000));
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
));
163 gbt_tstz_compress(PG_FUNCTION_ARGS
)
165 GISTENTRY
*entry
= (GISTENTRY
*) PG_GETARG_POINTER(0);
170 tsKEY
*r
= (tsKEY
*) palloc(sizeof(tsKEY
));
171 TimestampTz ts
= DatumGetTimestampTz(entry
->key
);
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
);
185 PG_RETURN_POINTER(retval
);
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
);
200 /* All cases served by this function are exact */
203 key
.lower
= (GBT_NUMKEY
*) & kkk
->lower
;
204 key
.upper
= (GBT_NUMKEY
*) & kkk
->upper
;
207 gbt_num_consistent(&key
, (void *) &query
, &strategy
, GIST_LEAF(entry
), &tinfo
)
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
);
223 /* All cases served by this function are exact */
226 key
.lower
= (GBT_NUMKEY
*) & kkk
[0];
227 key
.upper
= (GBT_NUMKEY
*) & kkk
[MAXALIGN(tinfo
.size
)];
228 qqq
= tstz_to_ts_gmt(query
);
231 gbt_num_consistent(&key
, (void *) &qqq
, &strategy
, GIST_LEAF(entry
), &tinfo
)
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 ) \
250 if ( val < -FLT_MAX ) \
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);
267 * We are allways using "double" timestamps here. Precision should be good
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
);
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),
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
);