PostgreSQL Source Code: contrib/btree_gist/btree_time.c Source File

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/rel.h"
11#include "utils/sortsupport.h"
12#include "utils/timestamp.h"
13
14 typedef struct
15{
16 TimeADT lower;
17 TimeADT upper;
18} timeKEY;
19
20/* GiST support functions */
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);
31 PG_FUNCTION_INFO_V1(gbt_time_sortsupport);
32 PG_FUNCTION_INFO_V1(gbt_timetz_sortsupport);
33
34
35static bool
36 gbt_timegt(const void *a, const void *b, FmgrInfo *flinfo)
37{
38 const TimeADT *aa = (const TimeADT *) a;
39 const TimeADT *bb = (const TimeADT *) b;
40
41 return DatumGetBool(DirectFunctionCall2(time_gt,
42 TimeADTGetDatum(*aa),
43 TimeADTGetDatum(*bb)));
44}
45
46static bool
47 gbt_timege(const void *a, const void *b, FmgrInfo *flinfo)
48{
49 const TimeADT *aa = (const TimeADT *) a;
50 const TimeADT *bb = (const TimeADT *) b;
51
52 return DatumGetBool(DirectFunctionCall2(time_ge,
53 TimeADTGetDatum(*aa),
54 TimeADTGetDatum(*bb)));
55}
56
57static bool
58 gbt_timeeq(const void *a, const void *b, FmgrInfo *flinfo)
59{
60 const TimeADT *aa = (const TimeADT *) a;
61 const TimeADT *bb = (const TimeADT *) b;
62
63 return DatumGetBool(DirectFunctionCall2(time_eq,
64 TimeADTGetDatum(*aa),
65 TimeADTGetDatum(*bb)));
66}
67
68static bool
69 gbt_timele(const void *a, const void *b, FmgrInfo *flinfo)
70{
71 const TimeADT *aa = (const TimeADT *) a;
72 const TimeADT *bb = (const TimeADT *) b;
73
74 return DatumGetBool(DirectFunctionCall2(time_le,
75 TimeADTGetDatum(*aa),
76 TimeADTGetDatum(*bb)));
77}
78
79static bool
80 gbt_timelt(const void *a, const void *b, FmgrInfo *flinfo)
81{
82 const TimeADT *aa = (const TimeADT *) a;
83 const TimeADT *bb = (const TimeADT *) b;
84
85 return DatumGetBool(DirectFunctionCall2(time_lt,
86 TimeADTGetDatum(*aa),
87 TimeADTGetDatum(*bb)));
88}
89
90static int
91 gbt_timekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
92{
93 timeKEY *ia = (timeKEY *) (((const Nsrt *) a)->t);
94 timeKEY *ib = (timeKEY *) (((const Nsrt *) b)->t);
95 int res;
96
97 res = DatumGetInt32(DirectFunctionCall2(time_cmp, TimeADTGetDatum(ia->lower), TimeADTGetDatum(ib->lower)));
98 if (res == 0)
99 return DatumGetInt32(DirectFunctionCall2(time_cmp, TimeADTGetDatum(ia->upper), TimeADTGetDatum(ib->upper)));
100
101 return res;
102}
103
104static float8
105 gbt_time_dist(const void *a, const void *b, FmgrInfo *flinfo)
106{
107 const TimeADT *aa = (const TimeADT *) a;
108 const TimeADT *bb = (const TimeADT *) b;
109 Interval *i;
110
111 i = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
112 TimeADTGetDatum(*aa),
113 TimeADTGetDatum(*bb)));
114 return fabs(INTERVAL_TO_SEC(i));
115}
116
117
118 static const gbtree_ninfo tinfo =
119{
120 gbt_t_time,
121 sizeof(TimeADT),
122 16, /* sizeof(gbtreekey16) */
123 gbt_timegt,
124 gbt_timege,
125 gbt_timeeq,
126 gbt_timele,
127 gbt_timelt,
128 gbt_timekey_cmp,
129 gbt_time_dist
130};
131
132
133 PG_FUNCTION_INFO_V1(time_dist);
134Datum
135 time_dist(PG_FUNCTION_ARGS)
136{
137 Datum diff = DirectFunctionCall2(time_mi_time,
138 PG_GETARG_DATUM(0),
139 PG_GETARG_DATUM(1));
140
141 PG_RETURN_INTERVAL_P(abs_interval(DatumGetIntervalP(diff)));
142}
143
144
145/**************************************************
146 * GiST support functions
147 **************************************************/
148
149Datum
150 gbt_time_compress(PG_FUNCTION_ARGS)
151{
152 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
153
154 PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
155}
156
157Datum
158 gbt_timetz_compress(PG_FUNCTION_ARGS)
159{
160 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
161 GISTENTRY *retval;
162
163 if (entry->leafkey)
164 {
165 timeKEY *r = (timeKEY *) palloc(sizeof(timeKEY));
166 TimeTzADT *tz = DatumGetTimeTzADTP(entry->key);
167 TimeADT tmp;
168
169 retval = palloc(sizeof(GISTENTRY));
170
171 /* We are using the time + zone only to compress */
172 tmp = tz->time + (tz->zone * INT64CONST(1000000));
173 r->lower = r->upper = tmp;
174 gistentryinit(*retval, PointerGetDatum(r),
175 entry->rel, entry->page,
176 entry->offset, false);
177 }
178 else
179 retval = entry;
180 PG_RETURN_POINTER(retval);
181}
182
183Datum
184 gbt_time_fetch(PG_FUNCTION_ARGS)
185{
186 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
187
188 PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
189}
190
191Datum
192 gbt_time_consistent(PG_FUNCTION_ARGS)
193{
194 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
195 TimeADT query = PG_GETARG_TIMEADT(1);
196 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
197
198 /* Oid subtype = PG_GETARG_OID(3); */
199 bool *recheck = (bool *) PG_GETARG_POINTER(4);
200 timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
201 GBT_NUMKEY_R key;
202
203 /* All cases served by this function are exact */
204 *recheck = false;
205
206 key.lower = (GBT_NUMKEY *) &kkk->lower;
207 key.upper = (GBT_NUMKEY *) &kkk->upper;
208
209 PG_RETURN_BOOL(gbt_num_consistent(&key, &query, &strategy,
210 GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
211}
212
213Datum
214 gbt_time_distance(PG_FUNCTION_ARGS)
215{
216 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
217 TimeADT query = PG_GETARG_TIMEADT(1);
218
219 /* Oid subtype = PG_GETARG_OID(3); */
220 timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
221 GBT_NUMKEY_R key;
222
223 key.lower = (GBT_NUMKEY *) &kkk->lower;
224 key.upper = (GBT_NUMKEY *) &kkk->upper;
225
226 PG_RETURN_FLOAT8(gbt_num_distance(&key, &query, GIST_LEAF(entry),
227 &tinfo, fcinfo->flinfo));
228}
229
230Datum
231 gbt_timetz_consistent(PG_FUNCTION_ARGS)
232{
233 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
234 TimeTzADT *query = PG_GETARG_TIMETZADT_P(1);
235 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
236
237 /* Oid subtype = PG_GETARG_OID(3); */
238 bool *recheck = (bool *) PG_GETARG_POINTER(4);
239 timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
240 TimeADT qqq;
241 GBT_NUMKEY_R key;
242
243 /* All cases served by this function are inexact */
244 *recheck = true;
245
246 qqq = query->time + (query->zone * INT64CONST(1000000));
247
248 key.lower = (GBT_NUMKEY *) &kkk->lower;
249 key.upper = (GBT_NUMKEY *) &kkk->upper;
250
251 PG_RETURN_BOOL(gbt_num_consistent(&key, &qqq, &strategy,
252 GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
253}
254
255Datum
256 gbt_time_union(PG_FUNCTION_ARGS)
257{
258 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
259 void *out = palloc(sizeof(timeKEY));
260
261 *(int *) PG_GETARG_POINTER(1) = sizeof(timeKEY);
262 PG_RETURN_POINTER(gbt_num_union(out, entryvec, &tinfo, fcinfo->flinfo));
263}
264
265Datum
266 gbt_time_penalty(PG_FUNCTION_ARGS)
267{
268 timeKEY *origentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
269 timeKEY *newentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
270 float *result = (float *) PG_GETARG_POINTER(2);
271 Interval *intr;
272 double res;
273 double res2;
274
275 intr = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
276 TimeADTGetDatum(newentry->upper),
277 TimeADTGetDatum(origentry->upper)));
278 res = INTERVAL_TO_SEC(intr);
279 res = Max(res, 0);
280
281 intr = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
282 TimeADTGetDatum(origentry->lower),
283 TimeADTGetDatum(newentry->lower)));
284 res2 = INTERVAL_TO_SEC(intr);
285 res2 = Max(res2, 0);
286
287 res += res2;
288
289 *result = 0.0;
290
291 if (res > 0)
292 {
293 intr = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
294 TimeADTGetDatum(origentry->upper),
295 TimeADTGetDatum(origentry->lower)));
296 *result += FLT_MIN;
297 *result += (float) (res / (res + INTERVAL_TO_SEC(intr)));
298 *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
299 }
300
301 PG_RETURN_POINTER(result);
302}
303
304Datum
305 gbt_time_picksplit(PG_FUNCTION_ARGS)
306{
307 PG_RETURN_POINTER(gbt_num_picksplit((GistEntryVector *) PG_GETARG_POINTER(0),
308 (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
309 &tinfo, fcinfo->flinfo));
310}
311
312Datum
313 gbt_time_same(PG_FUNCTION_ARGS)
314{
315 timeKEY *b1 = (timeKEY *) PG_GETARG_POINTER(0);
316 timeKEY *b2 = (timeKEY *) PG_GETARG_POINTER(1);
317 bool *result = (bool *) PG_GETARG_POINTER(2);
318
319 *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
320 PG_RETURN_POINTER(result);
321}
322
323static int
324 gbt_timekey_ssup_cmp(Datum x, Datum y, SortSupport ssup)
325{
326 timeKEY *arg1 = (timeKEY *) DatumGetPointer(x);
327 timeKEY *arg2 = (timeKEY *) DatumGetPointer(y);
328
329 /* for leaf items we expect lower == upper, so only compare lower */
330 return DatumGetInt32(DirectFunctionCall2(time_cmp,
331 TimeADTGetDatum(arg1->lower),
332 TimeADTGetDatum(arg2->lower)));
333}
334
335Datum
336 gbt_time_sortsupport(PG_FUNCTION_ARGS)
337{
338 SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
339
340 ssup->comparator = gbt_timekey_ssup_cmp;
341 ssup->ssup_extra = NULL;
342
343 PG_RETURN_VOID();
344}
@ 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:58
Datum gbt_time_distance(PG_FUNCTION_ARGS)
Definition: btree_time.c:214
Datum gbt_time_same(PG_FUNCTION_ARGS)
Definition: btree_time.c:313
Datum gbt_time_fetch(PG_FUNCTION_ARGS)
Definition: btree_time.c:184
static int gbt_timekey_ssup_cmp(Datum x, Datum y, SortSupport ssup)
Definition: btree_time.c:324
Datum gbt_time_compress(PG_FUNCTION_ARGS)
Definition: btree_time.c:150
Datum time_dist(PG_FUNCTION_ARGS)
Definition: btree_time.c:135
Datum gbt_time_penalty(PG_FUNCTION_ARGS)
Definition: btree_time.c:266
Datum gbt_time_consistent(PG_FUNCTION_ARGS)
Definition: btree_time.c:192
Datum gbt_timetz_compress(PG_FUNCTION_ARGS)
Definition: btree_time.c:158
Datum gbt_time_sortsupport(PG_FUNCTION_ARGS)
Definition: btree_time.c:336
static bool gbt_timele(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:69
static const gbtree_ninfo tinfo
Definition: btree_time.c:118
Datum gbt_timetz_consistent(PG_FUNCTION_ARGS)
Definition: btree_time.c:231
Datum gbt_time_picksplit(PG_FUNCTION_ARGS)
Definition: btree_time.c:305
static bool gbt_timelt(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:80
Datum gbt_time_union(PG_FUNCTION_ARGS)
Definition: btree_time.c:256
PG_FUNCTION_INFO_V1(gbt_time_compress)
static bool gbt_timegt(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:36
static bool gbt_timege(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:47
static int gbt_timekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:91
static float8 gbt_time_dist(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:105
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:552
#define Max(x, y)
Definition: c.h:997
double float8
Definition: c.h:635
Datum time_eq(PG_FUNCTION_ARGS)
Definition: date.c:1827
Datum time_le(PG_FUNCTION_ARGS)
Definition: date.c:1854
Datum time_cmp(PG_FUNCTION_ARGS)
Definition: date.c:1881
Datum time_mi_time(PG_FUNCTION_ARGS)
Definition: date.c:2180
Datum time_ge(PG_FUNCTION_ARGS)
Definition: date.c:1872
Datum time_lt(PG_FUNCTION_ARGS)
Definition: date.c:1845
Datum time_gt(PG_FUNCTION_ARGS)
Definition: date.c:1863
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
static Datum TimeADTGetDatum(TimeADT X)
Definition: date.h:78
#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
y
int y
Definition: isn.c:76
b
int b
Definition: isn.c:74
x
int x
Definition: isn.c:75
a
int a
Definition: isn.c:73
i
int i
Definition: isn.c:77
void * palloc(Size size)
Definition: mcxt.c:1365
static bool DatumGetBool(Datum X)
Definition: postgres.h:100
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:332
uint64_t Datum
Definition: postgres.h:70
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:322
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:212
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
uint16 StrategyNumber
Definition: stratnum.h:22
Definition: fmgr.h:57
Definition: gist.h:160
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:16
TimeADT upper
Definition: btree_time.c:17
static Interval * DatumGetIntervalP(Datum X)
Definition: timestamp.h:40
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:69

AltStyle によって変換されたページ (->オリジナル) /