PostgreSQL Source Code git master
btree_time.c
Go to the documentation of this file.
1/*
2 * contrib/btree_gist/btree_time.c
3 */
4#include "postgres.h"
5
6#include "btree_gist.h"
7#include "btree_utils_num.h"
8#include "utils/fmgrprotos.h"
9#include "utils/date.h"
10#include "utils/sortsupport.h"
11#include "utils/timestamp.h"
12
13typedef struct
14{
17} timeKEY;
18
19/* GiST support functions */
31PG_FUNCTION_INFO_V1(gbt_timetz_sortsupport);
32
33
34#ifdef USE_FLOAT8_BYVAL
35#define TimeADTGetDatumFast(X) TimeADTGetDatum(X)
36#else
37#define TimeADTGetDatumFast(X) PointerGetDatum(&(X))
38#endif
39
40
41static bool
42gbt_timegt(const void *a, const void *b, FmgrInfo *flinfo)
43{
44 const TimeADT *aa = (const TimeADT *) a;
45 const TimeADT *bb = (const TimeADT *) b;
46
50}
51
52static bool
53gbt_timege(const void *a, const void *b, FmgrInfo *flinfo)
54{
55 const TimeADT *aa = (const TimeADT *) a;
56 const TimeADT *bb = (const TimeADT *) b;
57
61}
62
63static bool
64gbt_timeeq(const void *a, const void *b, FmgrInfo *flinfo)
65{
66 const TimeADT *aa = (const TimeADT *) a;
67 const TimeADT *bb = (const TimeADT *) b;
68
72}
73
74static bool
75gbt_timele(const void *a, const void *b, FmgrInfo *flinfo)
76{
77 const TimeADT *aa = (const TimeADT *) a;
78 const TimeADT *bb = (const TimeADT *) b;
79
83}
84
85static bool
86gbt_timelt(const void *a, const void *b, FmgrInfo *flinfo)
87{
88 const TimeADT *aa = (const TimeADT *) a;
89 const TimeADT *bb = (const TimeADT *) b;
90
94}
95
96static int
97gbt_timekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
98{
99 timeKEY *ia = (timeKEY *) (((const Nsrt *) a)->t);
100 timeKEY *ib = (timeKEY *) (((const Nsrt *) b)->t);
101 int res;
102
104 if (res == 0)
106
107 return res;
108}
109
110static float8
111gbt_time_dist(const void *a, const void *b, FmgrInfo *flinfo)
112{
113 const TimeADT *aa = (const TimeADT *) a;
114 const TimeADT *bb = (const TimeADT *) b;
115 Interval *i;
116
119 TimeADTGetDatumFast(*bb)));
120 return fabs(INTERVAL_TO_SEC(i));
121}
122
123
124static const gbtree_ninfo tinfo =
125{
127 sizeof(TimeADT),
128 16, /* sizeof(gbtreekey16) */
136};
137
138
140Datum
142{
145 PG_GETARG_DATUM(1));
146
148}
149
150
151/**************************************************
152 * GiST support functions
153 **************************************************/
154
155Datum
157{
158 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
159
161}
162
163Datum
165{
166 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
167 GISTENTRY *retval;
168
169 if (entry->leafkey)
170 {
171 timeKEY *r = (timeKEY *) palloc(sizeof(timeKEY));
172 TimeTzADT *tz = DatumGetTimeTzADTP(entry->key);
173 TimeADT tmp;
174
175 retval = palloc(sizeof(GISTENTRY));
176
177 /* We are using the time + zone only to compress */
178 tmp = tz->time + (tz->zone * INT64CONST(1000000));
179 r->lower = r->upper = tmp;
180 gistentryinit(*retval, PointerGetDatum(r),
181 entry->rel, entry->page,
182 entry->offset, false);
183 }
184 else
185 retval = entry;
186 PG_RETURN_POINTER(retval);
187}
188
189Datum
191{
192 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
193
195}
196
197Datum
199{
200 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
201 TimeADT query = PG_GETARG_TIMEADT(1);
203
204 /* Oid subtype = PG_GETARG_OID(3); */
205 bool *recheck = (bool *) PG_GETARG_POINTER(4);
206 timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
208
209 /* All cases served by this function are exact */
210 *recheck = false;
211
212 key.lower = (GBT_NUMKEY *) &kkk->lower;
213 key.upper = (GBT_NUMKEY *) &kkk->upper;
214
215 PG_RETURN_BOOL(gbt_num_consistent(&key, &query, &strategy,
216 GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
217}
218
219Datum
221{
222 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
223 TimeADT query = PG_GETARG_TIMEADT(1);
224
225 /* Oid subtype = PG_GETARG_OID(3); */
226 timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
228
229 key.lower = (GBT_NUMKEY *) &kkk->lower;
230 key.upper = (GBT_NUMKEY *) &kkk->upper;
231
233 &tinfo, fcinfo->flinfo));
234}
235
236Datum
238{
239 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
242
243 /* Oid subtype = PG_GETARG_OID(3); */
244 bool *recheck = (bool *) PG_GETARG_POINTER(4);
245 timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
246 TimeADT qqq;
248
249 /* All cases served by this function are inexact */
250 *recheck = true;
251
252 qqq = query->time + (query->zone * INT64CONST(1000000));
253
254 key.lower = (GBT_NUMKEY *) &kkk->lower;
255 key.upper = (GBT_NUMKEY *) &kkk->upper;
256
257 PG_RETURN_BOOL(gbt_num_consistent(&key, &qqq, &strategy,
258 GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
259}
260
261Datum
263{
265 void *out = palloc(sizeof(timeKEY));
266
267 *(int *) PG_GETARG_POINTER(1) = sizeof(timeKEY);
268 PG_RETURN_POINTER(gbt_num_union(out, entryvec, &tinfo, fcinfo->flinfo));
269}
270
271Datum
273{
274 timeKEY *origentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
276 float *result = (float *) PG_GETARG_POINTER(2);
277 Interval *intr;
278 double res;
279 double res2;
280
282 TimeADTGetDatumFast(newentry->upper),
283 TimeADTGetDatumFast(origentry->upper)));
284 res = INTERVAL_TO_SEC(intr);
285 res = Max(res, 0);
286
288 TimeADTGetDatumFast(origentry->lower),
289 TimeADTGetDatumFast(newentry->lower)));
290 res2 = INTERVAL_TO_SEC(intr);
291 res2 = Max(res2, 0);
292
293 res += res2;
294
295 *result = 0.0;
296
297 if (res > 0)
298 {
300 TimeADTGetDatumFast(origentry->upper),
301 TimeADTGetDatumFast(origentry->lower)));
302 *result += FLT_MIN;
303 *result += (float) (res / (res + INTERVAL_TO_SEC(intr)));
304 *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
305 }
306
307 PG_RETURN_POINTER(result);
308}
309
310Datum
312{
315 &tinfo, fcinfo->flinfo));
316}
317
318Datum
320{
321 timeKEY *b1 = (timeKEY *) PG_GETARG_POINTER(0);
322 timeKEY *b2 = (timeKEY *) PG_GETARG_POINTER(1);
323 bool *result = (bool *) PG_GETARG_POINTER(2);
324
325 *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
326 PG_RETURN_POINTER(result);
327}
328
329static int
331{
332 timeKEY *arg1 = (timeKEY *) DatumGetPointer(x);
333 timeKEY *arg2 = (timeKEY *) DatumGetPointer(y);
334
335 /* for leaf items we expect lower == upper, so only compare lower */
338 TimeADTGetDatumFast(arg2->lower)));
339}
340
341Datum
343{
345
347 ssup->ssup_extra = NULL;
348
350}
@ gbt_t_time
Definition: btree_gist.h:26
Interval * abs_interval(Interval *a)
static bool gbt_timeeq(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:64
Datum gbt_time_distance(PG_FUNCTION_ARGS)
Definition: btree_time.c:220
Datum gbt_time_same(PG_FUNCTION_ARGS)
Definition: btree_time.c:319
Datum gbt_time_fetch(PG_FUNCTION_ARGS)
Definition: btree_time.c:190
static int gbt_timekey_ssup_cmp(Datum x, Datum y, SortSupport ssup)
Definition: btree_time.c:330
Datum gbt_time_compress(PG_FUNCTION_ARGS)
Definition: btree_time.c:156
Datum time_dist(PG_FUNCTION_ARGS)
Definition: btree_time.c:141
Datum gbt_time_penalty(PG_FUNCTION_ARGS)
Definition: btree_time.c:272
Datum gbt_time_consistent(PG_FUNCTION_ARGS)
Definition: btree_time.c:198
#define TimeADTGetDatumFast(X)
Definition: btree_time.c:37
Datum gbt_timetz_compress(PG_FUNCTION_ARGS)
Definition: btree_time.c:164
Datum gbt_time_sortsupport(PG_FUNCTION_ARGS)
Definition: btree_time.c:342
static bool gbt_timele(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:75
static const gbtree_ninfo tinfo
Definition: btree_time.c:124
Datum gbt_timetz_consistent(PG_FUNCTION_ARGS)
Definition: btree_time.c:237
Datum gbt_time_picksplit(PG_FUNCTION_ARGS)
Definition: btree_time.c:311
static bool gbt_timelt(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:86
Datum gbt_time_union(PG_FUNCTION_ARGS)
Definition: btree_time.c:262
PG_FUNCTION_INFO_V1(gbt_time_compress)
static bool gbt_timegt(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:42
static bool gbt_timege(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:53
static int gbt_timekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:97
static float8 gbt_time_dist(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:111
GISTENTRY * gbt_num_compress(GISTENTRY *entry, const gbtree_ninfo *tinfo)
float8 gbt_num_distance(const GBT_NUMKEY_R *key, const void *query, bool is_leaf, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
bool gbt_num_consistent(const GBT_NUMKEY_R *key, const void *query, const StrategyNumber *strategy, bool is_leaf, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
bool gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
GISTENTRY * gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo)
GIST_SPLITVEC * gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
void * gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
#define INTERVAL_TO_SEC(ivp)
char GBT_NUMKEY
#define INT64CONST(x)
Definition: c.h:516
#define Max(x, y)
Definition: c.h:969
double float8
Definition: c.h:601
Datum time_eq(PG_FUNCTION_ARGS)
Definition: date.c:1745
Datum time_le(PG_FUNCTION_ARGS)
Definition: date.c:1772
Datum time_cmp(PG_FUNCTION_ARGS)
Definition: date.c:1799
Datum time_mi_time(PG_FUNCTION_ARGS)
Definition: date.c:2098
Datum time_ge(PG_FUNCTION_ARGS)
Definition: date.c:1790
Datum time_lt(PG_FUNCTION_ARGS)
Definition: date.c:1763
Datum time_gt(PG_FUNCTION_ARGS)
Definition: date.c:1781
static TimeTzADT * DatumGetTimeTzADTP(Datum X)
Definition: date.h:66
#define PG_GETARG_TIMEADT(n)
Definition: date.h:90
int64 TimeADT
Definition: date.h:25
#define PG_GETARG_TIMETZADT_P(n)
Definition: date.h:91
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:684
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:367
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:272
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define GIST_LEAF(entry)
Definition: gist.h:171
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:245
int y
Definition: isn.c:76
int b
Definition: isn.c:74
int x
Definition: isn.c:75
int a
Definition: isn.c:73
int i
Definition: isn.c:77
void * palloc(Size size)
Definition: mcxt.c:1943
static bool DatumGetBool(Datum X)
Definition: postgres.h:95
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
uintptr_t Datum
Definition: postgres.h:69
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:317
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:207
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
uint16 StrategyNumber
Definition: stratnum.h:22
Definition: fmgr.h:57
OffsetNumber offset
Definition: gist.h:164
Datum key
Definition: gist.h:161
Page page
Definition: gist.h:163
Relation rel
Definition: gist.h:162
bool leafkey
Definition: gist.h:165
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:106
void * ssup_extra
Definition: sortsupport.h:87
Definition: date.h:28
TimeADT time
Definition: date.h:29
int32 zone
Definition: date.h:30
TimeADT lower
Definition: btree_time.c:15
TimeADT upper
Definition: btree_time.c:16
static Interval * DatumGetIntervalP(Datum X)
Definition: timestamp.h:40
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:69