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_timetz_consistent
);
24 PG_FUNCTION_INFO_V1(gbt_time_penalty
);
25 PG_FUNCTION_INFO_V1(gbt_time_same
);
27 Datum
gbt_time_compress(PG_FUNCTION_ARGS
);
28 Datum
gbt_timetz_compress(PG_FUNCTION_ARGS
);
29 Datum
gbt_time_union(PG_FUNCTION_ARGS
);
30 Datum
gbt_time_picksplit(PG_FUNCTION_ARGS
);
31 Datum
gbt_time_consistent(PG_FUNCTION_ARGS
);
32 Datum
gbt_timetz_consistent(PG_FUNCTION_ARGS
);
33 Datum
gbt_time_penalty(PG_FUNCTION_ARGS
);
34 Datum
gbt_time_same(PG_FUNCTION_ARGS
);
37 #ifdef USE_FLOAT8_BYVAL
38 #define TimeADTGetDatumFast(X) TimeADTGetDatum(X)
40 #define TimeADTGetDatumFast(X) PointerGetDatum(&(X))
45 gbt_timegt(const void *a
, const void *b
)
47 const TimeADT
*aa
= (const TimeADT
*) a
;
48 const TimeADT
*bb
= (const TimeADT
*) b
;
50 return DatumGetBool(DirectFunctionCall2(time_gt
,
51 TimeADTGetDatumFast(*aa
),
52 TimeADTGetDatumFast(*bb
)));
56 gbt_timege(const void *a
, const void *b
)
58 const TimeADT
*aa
= (const TimeADT
*) a
;
59 const TimeADT
*bb
= (const TimeADT
*) b
;
61 return DatumGetBool(DirectFunctionCall2(time_ge
,
62 TimeADTGetDatumFast(*aa
),
63 TimeADTGetDatumFast(*bb
)));
67 gbt_timeeq(const void *a
, const void *b
)
69 const TimeADT
*aa
= (const TimeADT
*) a
;
70 const TimeADT
*bb
= (const TimeADT
*) b
;
72 return DatumGetBool(DirectFunctionCall2(time_eq
,
73 TimeADTGetDatumFast(*aa
),
74 TimeADTGetDatumFast(*bb
)));
78 gbt_timele(const void *a
, const void *b
)
80 const TimeADT
*aa
= (const TimeADT
*) a
;
81 const TimeADT
*bb
= (const TimeADT
*) b
;
83 return DatumGetBool(DirectFunctionCall2(time_le
,
84 TimeADTGetDatumFast(*aa
),
85 TimeADTGetDatumFast(*bb
)));
89 gbt_timelt(const void *a
, const void *b
)
91 const TimeADT
*aa
= (const TimeADT
*) a
;
92 const TimeADT
*bb
= (const TimeADT
*) b
;
94 return DatumGetBool(DirectFunctionCall2(time_lt
,
95 TimeADTGetDatumFast(*aa
),
96 TimeADTGetDatumFast(*bb
)));
102 gbt_timekey_cmp(const void *a
, const void *b
)
104 if (gbt_timegt((void *) &(((Nsrt
*) a
)->t
[0]), (void *) &(((Nsrt
*) b
)->t
[0])))
106 else if (gbt_timelt((void *) &(((Nsrt
*) a
)->t
[0]), (void *) &(((Nsrt
*) b
)->t
[0])))
112 static const gbtree_ninfo tinfo
=
125 /**************************************************
127 **************************************************/
132 gbt_time_compress(PG_FUNCTION_ARGS
)
134 GISTENTRY
*entry
= (GISTENTRY
*) PG_GETARG_POINTER(0);
135 GISTENTRY
*retval
= NULL
;
137 PG_RETURN_POINTER(gbt_num_compress(retval
, entry
, &tinfo
));
142 gbt_timetz_compress(PG_FUNCTION_ARGS
)
144 GISTENTRY
*entry
= (GISTENTRY
*) PG_GETARG_POINTER(0);
149 timeKEY
*r
= (timeKEY
*) palloc(sizeof(timeKEY
));
150 TimeTzADT
*tz
= DatumGetTimeTzADTP(entry
->key
);
153 retval
= palloc(sizeof(GISTENTRY
));
155 /* We are using the time + zone only to compress */
156 #ifdef HAVE_INT64_TIMESTAMP
157 tmp
= tz
->time
+ (tz
->zone
* INT64CONST(1000000));
159 tmp
= (tz
->time
+ tz
->zone
);
161 r
->lower
= r
->upper
= tmp
;
162 gistentryinit(*retval
, PointerGetDatum(r
),
163 entry
->rel
, entry
->page
,
164 entry
->offset
, FALSE
);
168 PG_RETURN_POINTER(retval
);
173 gbt_time_consistent(PG_FUNCTION_ARGS
)
175 GISTENTRY
*entry
= (GISTENTRY
*) PG_GETARG_POINTER(0);
176 TimeADT query
= PG_GETARG_TIMEADT(1);
177 StrategyNumber strategy
= (StrategyNumber
) PG_GETARG_UINT16(2);
179 /* Oid subtype = PG_GETARG_OID(3); */
180 bool *recheck
= (bool *) PG_GETARG_POINTER(4);
181 timeKEY
*kkk
= (timeKEY
*) DatumGetPointer(entry
->key
);
184 /* All cases served by this function are exact */
187 key
.lower
= (GBT_NUMKEY
*) &kkk
->lower
;
188 key
.upper
= (GBT_NUMKEY
*) &kkk
->upper
;
191 gbt_num_consistent(&key
, (void *) &query
, &strategy
, GIST_LEAF(entry
), &tinfo
)
196 gbt_timetz_consistent(PG_FUNCTION_ARGS
)
198 GISTENTRY
*entry
= (GISTENTRY
*) PG_GETARG_POINTER(0);
199 TimeTzADT
*query
= PG_GETARG_TIMETZADT_P(1);
200 StrategyNumber strategy
= (StrategyNumber
) PG_GETARG_UINT16(2);
202 /* Oid subtype = PG_GETARG_OID(3); */
203 bool *recheck
= (bool *) PG_GETARG_POINTER(4);
204 timeKEY
*kkk
= (timeKEY
*) DatumGetPointer(entry
->key
);
208 /* All cases served by this function are inexact */
211 #ifdef HAVE_INT64_TIMESTAMP
212 qqq
= query
->time
+ (query
->zone
* INT64CONST(1000000));
214 qqq
= (query
->time
+ query
->zone
);
217 key
.lower
= (GBT_NUMKEY
*) &kkk
->lower
;
218 key
.upper
= (GBT_NUMKEY
*) &kkk
->upper
;
221 gbt_num_consistent(&key
, (void *) &qqq
, &strategy
, GIST_LEAF(entry
), &tinfo
)
227 gbt_time_union(PG_FUNCTION_ARGS
)
229 GistEntryVector
*entryvec
= (GistEntryVector
*) PG_GETARG_POINTER(0);
230 void *out
= palloc(sizeof(timeKEY
));
232 *(int *) PG_GETARG_POINTER(1) = sizeof(timeKEY
);
233 PG_RETURN_POINTER(gbt_num_union((void *) out
, entryvec
, &tinfo
));
238 gbt_time_penalty(PG_FUNCTION_ARGS
)
240 timeKEY
*origentry
= (timeKEY
*) DatumGetPointer(((GISTENTRY
*) PG_GETARG_POINTER(0))->key
);
241 timeKEY
*newentry
= (timeKEY
*) DatumGetPointer(((GISTENTRY
*) PG_GETARG_POINTER(1))->key
);
242 float *result
= (float *) PG_GETARG_POINTER(2);
247 intr
= DatumGetIntervalP(DirectFunctionCall2(
249 TimeADTGetDatumFast(newentry
->upper
),
250 TimeADTGetDatumFast(origentry
->upper
)));
251 res
= INTERVAL_TO_SEC(intr
);
254 intr
= DatumGetIntervalP(DirectFunctionCall2(
256 TimeADTGetDatumFast(origentry
->lower
),
257 TimeADTGetDatumFast(newentry
->lower
)));
258 res2
= INTERVAL_TO_SEC(intr
);
267 intr
= DatumGetIntervalP(DirectFunctionCall2(
269 TimeADTGetDatumFast(origentry
->upper
),
270 TimeADTGetDatumFast(origentry
->lower
)));
272 *result
+= (float) (res
/ (res
+ INTERVAL_TO_SEC(intr
)));
273 *result
*= (FLT_MAX
/ (((GISTENTRY
*) PG_GETARG_POINTER(0))->rel
->rd_att
->natts
+ 1));
276 PG_RETURN_POINTER(result
);
281 gbt_time_picksplit(PG_FUNCTION_ARGS
)
283 PG_RETURN_POINTER(gbt_num_picksplit(
284 (GistEntryVector
*) PG_GETARG_POINTER(0),
285 (GIST_SPLITVEC
*) PG_GETARG_POINTER(1),
291 gbt_time_same(PG_FUNCTION_ARGS
)
293 timeKEY
*b1
= (timeKEY
*) PG_GETARG_POINTER(0);
294 timeKEY
*b2
= (timeKEY
*) PG_GETARG_POINTER(1);
295 bool *result
= (bool *) PG_GETARG_POINTER(2);
297 *result
= gbt_num_same((void *) b1
, (void *) b2
, &tinfo
);
298 PG_RETURN_POINTER(result
);