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/builtins.h"
9 #include "utils/date.h"
10 #include "utils/timestamp.h"
11 
12 typedef struct
13 {
16 } timeKEY;
17 
18 /*
19 ** time ops
20 */
31 
32 
33 #ifdef USE_FLOAT8_BYVAL
34 #define TimeADTGetDatumFast(X) TimeADTGetDatum(X)
35 #else
36 #define TimeADTGetDatumFast(X) PointerGetDatum(&(X))
37 #endif
38 
39 
40 static bool
41 gbt_timegt(const void *a, const void *b, FmgrInfo *flinfo)
42 {
43  const TimeADT *aa = (const TimeADT *) a;
44  const TimeADT *bb = (const TimeADT *) b;
45 
48  TimeADTGetDatumFast(*bb)));
49 }
50 
51 static bool
52 gbt_timege(const void *a, const void *b, FmgrInfo *flinfo)
53 {
54  const TimeADT *aa = (const TimeADT *) a;
55  const TimeADT *bb = (const TimeADT *) b;
56 
59  TimeADTGetDatumFast(*bb)));
60 }
61 
62 static bool
63 gbt_timeeq(const void *a, const void *b, FmgrInfo *flinfo)
64 {
65  const TimeADT *aa = (const TimeADT *) a;
66  const TimeADT *bb = (const TimeADT *) b;
67 
70  TimeADTGetDatumFast(*bb)));
71 }
72 
73 static bool
74 gbt_timele(const void *a, const void *b, FmgrInfo *flinfo)
75 {
76  const TimeADT *aa = (const TimeADT *) a;
77  const TimeADT *bb = (const TimeADT *) b;
78 
81  TimeADTGetDatumFast(*bb)));
82 }
83 
84 static bool
85 gbt_timelt(const void *a, const void *b, FmgrInfo *flinfo)
86 {
87  const TimeADT *aa = (const TimeADT *) a;
88  const TimeADT *bb = (const TimeADT *) b;
89 
92  TimeADTGetDatumFast(*bb)));
93 }
94 
95 
96 
97 static int
98 gbt_timekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
99 {
100  timeKEY *ia = (timeKEY *) (((const Nsrt *) a)->t);
101  timeKEY *ib = (timeKEY *) (((const Nsrt *) b)->t);
102  int res;
103 
105  if (res == 0)
107 
108  return res;
109 }
110 
111 static float8
112 gbt_time_dist(const void *a, const void *b, FmgrInfo *flinfo)
113 {
114  const TimeADT *aa = (const TimeADT *) a;
115  const TimeADT *bb = (const TimeADT *) b;
116  Interval *i;
117 
119  TimeADTGetDatumFast(*aa),
120  TimeADTGetDatumFast(*bb)));
121  return (float8) Abs(INTERVAL_TO_SEC(i));
122 }
123 
124 
125 static const gbtree_ninfo tinfo =
126 {
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,
137 };
138 
139 
141 Datum
143 {
145  PG_GETARG_DATUM(0),
146  PG_GETARG_DATUM(1));
147 
149 }
150 
151 
152 /**************************************************
153  * time ops
154  **************************************************/
155 
156 
157 
158 Datum
160 {
161  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
162 
163  PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
164 }
165 
166 
167 Datum
169 {
170  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
171  GISTENTRY *retval;
172 
173  if (entry->leafkey)
174  {
175  timeKEY *r = (timeKEY *) palloc(sizeof(timeKEY));
176  TimeTzADT *tz = DatumGetTimeTzADTP(entry->key);
177  TimeADT tmp;
178 
179  retval = palloc(sizeof(GISTENTRY));
180 
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);
187  }
188  else
189  retval = entry;
190  PG_RETURN_POINTER(retval);
191 }
192 
193 Datum
195 {
196  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
197 
198  PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
199 }
200 
201 Datum
203 {
204  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
205  TimeADT query = PG_GETARG_TIMEADT(1);
207 
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;
212 
213  /* All cases served by this function are exact */
214  *recheck = false;
215 
216  key.lower = (GBT_NUMKEY *) &kkk->lower;
217  key.upper = (GBT_NUMKEY *) &kkk->upper;
218 
220  gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
221  );
222 }
223 
224 Datum
226 {
227  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
228  TimeADT query = PG_GETARG_TIMEADT(1);
229 
230  /* Oid subtype = PG_GETARG_OID(3); */
231  timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
232  GBT_NUMKEY_R key;
233 
234  key.lower = (GBT_NUMKEY *) &kkk->lower;
235  key.upper = (GBT_NUMKEY *) &kkk->upper;
236 
238  gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
239  );
240 }
241 
242 Datum
244 {
245  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
246  TimeTzADT *query = PG_GETARG_TIMETZADT_P(1);
248 
249  /* Oid subtype = PG_GETARG_OID(3); */
250  bool *recheck = (bool *) PG_GETARG_POINTER(4);
251  timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
252  TimeADT qqq;
253  GBT_NUMKEY_R key;
254 
255  /* All cases served by this function are inexact */
256  *recheck = true;
257 
258  qqq = query->time + (query->zone * INT64CONST(1000000));
259 
260  key.lower = (GBT_NUMKEY *) &kkk->lower;
261  key.upper = (GBT_NUMKEY *) &kkk->upper;
262 
264  gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo, fcinfo->flinfo)
265  );
266 }
267 
268 
269 Datum
271 {
273  void *out = palloc(sizeof(timeKEY));
274 
275  *(int *) PG_GETARG_POINTER(1) = sizeof(timeKEY);
276  PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
277 }
278 
279 
280 Datum
282 {
283  timeKEY *origentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
284  timeKEY *newentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
285  float *result = (float *) PG_GETARG_POINTER(2);
286  Interval *intr;
287  double res;
288  double res2;
289 
291  time_mi_time,
292  TimeADTGetDatumFast(newentry->upper),
293  TimeADTGetDatumFast(origentry->upper)));
294  res = INTERVAL_TO_SEC(intr);
295  res = Max(res, 0);
296 
298  time_mi_time,
299  TimeADTGetDatumFast(origentry->lower),
300  TimeADTGetDatumFast(newentry->lower)));
301  res2 = INTERVAL_TO_SEC(intr);
302  res2 = Max(res2, 0);
303 
304  res += res2;
305 
306  *result = 0.0;
307 
308  if (res > 0)
309  {
311  time_mi_time,
312  TimeADTGetDatumFast(origentry->upper),
313  TimeADTGetDatumFast(origentry->lower)));
314  *result += FLT_MIN;
315  *result += (float) (res / (res + INTERVAL_TO_SEC(intr)));
316  *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
317  }
318 
319  PG_RETURN_POINTER(result);
320 }
321 
322 
323 Datum
325 {
329  &tinfo, fcinfo->flinfo
330  ));
331 }
332 
333 Datum
335 {
336  timeKEY *b1 = (timeKEY *) PG_GETARG_POINTER(0);
337  timeKEY *b2 = (timeKEY *) PG_GETARG_POINTER(1);
338  bool *result = (bool *) PG_GETARG_POINTER(2);
339 
340  *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
341  PG_RETURN_POINTER(result);
342 }
#define GIST_LEAF(entry)
Definition: gist.h:133
Datum gbt_timetz_compress(PG_FUNCTION_ARGS)
Definition: btree_time.c:168
Relation rel
Definition: gist.h:124
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
bool gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
Definition: fmgr.h:56
#define DatumGetIntervalP(X)
Definition: timestamp.h:29
const GBT_NUMKEY * lower
#define TimeADTGetDatumFast(X)
Definition: btree_time.c:36
TimeADT time
Definition: date.h:28
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
float8 gbt_num_distance(const GBT_NUMKEY_R *key, const void *query, bool is_leaf, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
#define DatumGetInt32(X)
Definition: postgres.h:478
GISTENTRY * gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo)
#define PointerGetDatum(X)
Definition: postgres.h:562
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
Datum time_le(PG_FUNCTION_ARGS)
Definition: date.c:1466
static bool gbt_timele(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:74
Datum gbt_time_fetch(PG_FUNCTION_ARGS)
Definition: btree_time.c:194
#define DatumGetTimeTzADTP(X)
Definition: date.h:54
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:326
Datum time_eq(PG_FUNCTION_ARGS)
Definition: date.c:1439
TimeADT lower
Definition: btree_time.c:14
uint16 StrategyNumber
Definition: stratnum.h:22
const GBT_NUMKEY * upper
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
Datum time_dist(PG_FUNCTION_ARGS)
Definition: btree_time.c:142
bool gbt_num_consistent(const GBT_NUMKEY_R *key, const void *query, const StrategyNumber *strategy, bool is_leaf, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
Datum gbt_time_compress(PG_FUNCTION_ARGS)
Definition: btree_time.c:159
static bool gbt_timelt(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:85
Page page
Definition: gist.h:125
#define Abs(x)
Definition: c.h:808
GISTENTRY * gbt_num_compress(GISTENTRY *entry, const gbtree_ninfo *tinfo)
static const gbtree_ninfo tinfo
Definition: btree_time.c:125
static int gbt_timekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:98
double float8
Definition: c.h:429
Datum time_lt(PG_FUNCTION_ARGS)
Definition: date.c:1457
Datum time_cmp(PG_FUNCTION_ARGS)
Definition: date.c:1493
int32 zone
Definition: date.h:29
TimeADT upper
Definition: btree_time.c:15
Datum time_gt(PG_FUNCTION_ARGS)
Definition: date.c:1475
Datum key
Definition: gist.h:123
char GBT_NUMKEY
#define PG_GETARG_TIMETZADT_P(n)
Definition: date.h:62
#define DatumGetBool(X)
Definition: postgres.h:399
static bool gbt_timegt(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:41
int64 TimeADT
Definition: date.h:24
Datum gbt_time_picksplit(PG_FUNCTION_ARGS)
Definition: btree_time.c:324
bool leafkey
Definition: gist.h:127
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
uintptr_t Datum
Definition: postgres.h:372
Interval * abs_interval(Interval *a)
static float8 gbt_time_dist(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:112
#define Max(x, y)
Definition: c.h:796
Datum gbt_time_penalty(PG_FUNCTION_ARGS)
Definition: btree_time.c:281
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:169
Datum gbt_time_distance(PG_FUNCTION_ARGS)
Definition: btree_time.c:225
#define PG_GETARG_TIMEADT(n)
Definition: date.h:61
static bool gbt_timeeq(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:63
Datum gbt_time_same(PG_FUNCTION_ARGS)
Definition: btree_time.c:334
Datum gbt_time_consistent(PG_FUNCTION_ARGS)
Definition: btree_time.c:202
GIST_SPLITVEC * gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:237
#define DatumGetPointer(X)
Definition: postgres.h:555
Datum gbt_time_union(PG_FUNCTION_ARGS)
Definition: btree_time.c:270
void * palloc(Size size)
Definition: mcxt.c:848
Datum gbt_timetz_consistent(PG_FUNCTION_ARGS)
Definition: btree_time.c:243
Datum time_mi_time(PG_FUNCTION_ARGS)
Definition: date.c:1796
int i
static bool gbt_timege(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:52
#define PG_FUNCTION_ARGS
Definition: fmgr.h:158
Datum time_ge(PG_FUNCTION_ARGS)
Definition: date.c:1484
#define INTERVAL_TO_SEC(ivp)
Definition: date.h:26
OffsetNumber offset
Definition: gist.h:126
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:587
PG_FUNCTION_INFO_V1(gbt_time_compress)
void * gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)