pg_stat_statements: Avoid some locking during PGSS entry scans
[pgsql.git] / contrib / btree_gist / btree_time.c
blob3034bbb456bc99eecc08e53571a7e7129e9bbcfe
1 /*
2 * contrib/btree_gist/btree_time.c
3 */
4 #include "postgres.h"
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"
12 typedef struct
14 TimeADT lower;
15 TimeADT upper;
16 } timeKEY;
19 ** time ops
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)
35 #else
36 #define TimeADTGetDatumFast(X) PointerGetDatum(&(X))
37 #endif
40 static bool
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)));
51 static bool
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)));
62 static bool
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)));
73 static bool
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)));
84 static bool
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)));
97 static int
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);
102 int res;
104 res = DatumGetInt32(DirectFunctionCall2(time_cmp, TimeADTGetDatumFast(ia->lower), TimeADTGetDatumFast(ib->lower)));
105 if (res == 0)
106 return DatumGetInt32(DirectFunctionCall2(time_cmp, TimeADTGetDatumFast(ia->upper), TimeADTGetDatumFast(ib->upper)));
108 return res;
111 static float8
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;
116 Interval *i;
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 =
127 gbt_t_time,
128 sizeof(TimeADT),
129 16, /* sizeof(gbtreekey16) */
130 gbt_timegt,
131 gbt_timege,
132 gbt_timeeq,
133 gbt_timele,
134 gbt_timelt,
135 gbt_timekey_cmp,
136 gbt_time_dist
140 PG_FUNCTION_INFO_V1(time_dist);
141 Datum
142 time_dist(PG_FUNCTION_ARGS)
144 Datum diff = DirectFunctionCall2(time_mi_time,
145 PG_GETARG_DATUM(0),
146 PG_GETARG_DATUM(1));
148 PG_RETURN_INTERVAL_P(abs_interval(DatumGetIntervalP(diff)));
152 /**************************************************
153 * time ops
154 **************************************************/
158 Datum
159 gbt_time_compress(PG_FUNCTION_ARGS)
161 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
163 PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
167 Datum
168 gbt_timetz_compress(PG_FUNCTION_ARGS)
170 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
171 GISTENTRY *retval;
173 if (entry->leafkey)
175 timeKEY *r = (timeKEY *) palloc(sizeof(timeKEY));
176 TimeTzADT *tz = DatumGetTimeTzADTP(entry->key);
177 TimeADT tmp;
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);
188 else
189 retval = entry;
190 PG_RETURN_POINTER(retval);
193 Datum
194 gbt_time_fetch(PG_FUNCTION_ARGS)
196 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
198 PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
201 Datum
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);
211 GBT_NUMKEY_R key;
213 /* All cases served by this function are exact */
214 *recheck = false;
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));
223 Datum
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);
231 GBT_NUMKEY_R 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));
240 Datum
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);
250 TimeADT qqq;
251 GBT_NUMKEY_R key;
253 /* All cases served by this function are inexact */
254 *recheck = true;
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));
266 Datum
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));
277 Datum
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);
283 Interval *intr;
284 double res;
285 double res2;
287 intr = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
288 TimeADTGetDatumFast(newentry->upper),
289 TimeADTGetDatumFast(origentry->upper)));
290 res = INTERVAL_TO_SEC(intr);
291 res = Max(res, 0);
293 intr = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
294 TimeADTGetDatumFast(origentry->lower),
295 TimeADTGetDatumFast(newentry->lower)));
296 res2 = INTERVAL_TO_SEC(intr);
297 res2 = Max(res2, 0);
299 res += res2;
301 *result = 0.0;
303 if (res > 0)
305 intr = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
306 TimeADTGetDatumFast(origentry->upper),
307 TimeADTGetDatumFast(origentry->lower)));
308 *result += FLT_MIN;
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);
317 Datum
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));
325 Datum
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);