PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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)
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)
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)
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)
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)
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)
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)
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 #ifdef HAVE_INT64_TIMESTAMP
183  tmp = tz->time + (tz->zone * INT64CONST(1000000));
184 #else
185  tmp = (tz->time + tz->zone);
186 #endif
187  r->lower = r->upper = tmp;
188  gistentryinit(*retval, PointerGetDatum(r),
189  entry->rel, entry->page,
190  entry->offset, FALSE);
191  }
192  else
193  retval = entry;
194  PG_RETURN_POINTER(retval);
195 }
196 
197 Datum
199 {
200  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
201 
202  PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
203 }
204 
205 Datum
207 {
208  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
209  TimeADT query = PG_GETARG_TIMEADT(1);
211 
212  /* Oid subtype = PG_GETARG_OID(3); */
213  bool *recheck = (bool *) PG_GETARG_POINTER(4);
214  timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
215  GBT_NUMKEY_R key;
216 
217  /* All cases served by this function are exact */
218  *recheck = false;
219 
220  key.lower = (GBT_NUMKEY *) &kkk->lower;
221  key.upper = (GBT_NUMKEY *) &kkk->upper;
222 
224  gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
225  );
226 }
227 
228 Datum
230 {
231  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
232  TimeADT query = PG_GETARG_TIMEADT(1);
233 
234  /* Oid subtype = PG_GETARG_OID(3); */
235  timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
236  GBT_NUMKEY_R key;
237 
238  key.lower = (GBT_NUMKEY *) &kkk->lower;
239  key.upper = (GBT_NUMKEY *) &kkk->upper;
240 
242  gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry), &tinfo)
243  );
244 }
245 
246 Datum
248 {
249  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
250  TimeTzADT *query = PG_GETARG_TIMETZADT_P(1);
252 
253  /* Oid subtype = PG_GETARG_OID(3); */
254  bool *recheck = (bool *) PG_GETARG_POINTER(4);
255  timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
256  TimeADT qqq;
257  GBT_NUMKEY_R key;
258 
259  /* All cases served by this function are inexact */
260  *recheck = true;
261 
262 #ifdef HAVE_INT64_TIMESTAMP
263  qqq = query->time + (query->zone * INT64CONST(1000000));
264 #else
265  qqq = (query->time + query->zone);
266 #endif
267 
268  key.lower = (GBT_NUMKEY *) &kkk->lower;
269  key.upper = (GBT_NUMKEY *) &kkk->upper;
270 
272  gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo)
273  );
274 }
275 
276 
277 Datum
279 {
281  void *out = palloc(sizeof(timeKEY));
282 
283  *(int *) PG_GETARG_POINTER(1) = sizeof(timeKEY);
284  PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
285 }
286 
287 
288 Datum
290 {
291  timeKEY *origentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
292  timeKEY *newentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
293  float *result = (float *) PG_GETARG_POINTER(2);
294  Interval *intr;
295  double res;
296  double res2;
297 
299  time_mi_time,
300  TimeADTGetDatumFast(newentry->upper),
301  TimeADTGetDatumFast(origentry->upper)));
302  res = INTERVAL_TO_SEC(intr);
303  res = Max(res, 0);
304 
306  time_mi_time,
307  TimeADTGetDatumFast(origentry->lower),
308  TimeADTGetDatumFast(newentry->lower)));
309  res2 = INTERVAL_TO_SEC(intr);
310  res2 = Max(res2, 0);
311 
312  res += res2;
313 
314  *result = 0.0;
315 
316  if (res > 0)
317  {
319  time_mi_time,
320  TimeADTGetDatumFast(origentry->upper),
321  TimeADTGetDatumFast(origentry->lower)));
322  *result += FLT_MIN;
323  *result += (float) (res / (res + INTERVAL_TO_SEC(intr)));
324  *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
325  }
326 
327  PG_RETURN_POINTER(result);
328 }
329 
330 
331 Datum
333 {
337  &tinfo
338  ));
339 }
340 
341 Datum
343 {
344  timeKEY *b1 = (timeKEY *) PG_GETARG_POINTER(0);
345  timeKEY *b2 = (timeKEY *) PG_GETARG_POINTER(1);
346  bool *result = (bool *) PG_GETARG_POINTER(2);
347 
348  *result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
349  PG_RETURN_POINTER(result);
350 }
#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:305
static int gbt_timekey_cmp(const void *a, const void *b)
Definition: btree_time.c:98
static bool gbt_timelt(const void *a, const void *b)
Definition: btree_time.c:85
static float8 gbt_time_dist(const void *a, const void *b)
Definition: btree_time.c:112
#define DatumGetIntervalP(X)
Definition: timestamp.h:49
const GBT_NUMKEY * lower
#define TimeADTGetDatumFast(X)
Definition: btree_time.c:36
TimeADT time
Definition: date.h:32
static bool gbt_timege(const void *a, const void *b)
Definition: btree_time.c:52
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:61
#define DatumGetInt32(X)
Definition: postgres.h:480
GISTENTRY * gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo)
#define PointerGetDatum(X)
Definition: postgres.h:564
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:224
Datum time_le(PG_FUNCTION_ARGS)
Definition: date.c:1550
Datum gbt_time_fetch(PG_FUNCTION_ARGS)
Definition: btree_time.c:198
#define DatumGetTimeTzADTP(X)
Definition: date.h:75
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:310
Datum time_eq(PG_FUNCTION_ARGS)
Definition: date.c:1523
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:232
Datum time_dist(PG_FUNCTION_ARGS)
Definition: btree_time.c:142
Datum gbt_time_compress(PG_FUNCTION_ARGS)
Definition: btree_time.c:159
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
double float8
Definition: c.h:378
Datum time_lt(PG_FUNCTION_ARGS)
Definition: date.c:1541
Datum time_cmp(PG_FUNCTION_ARGS)
Definition: date.c:1577
#define FALSE
Definition: c.h:218
int32 zone
Definition: date.h:33
TimeADT upper
Definition: btree_time.c:15
Datum time_gt(PG_FUNCTION_ARGS)
Definition: date.c:1559
Datum key
Definition: gist.h:123
char GBT_NUMKEY
#define PG_GETARG_TIMETZADT_P(n)
Definition: date.h:84
#define DatumGetBool(X)
Definition: postgres.h:401
Datum gbt_time_picksplit(PG_FUNCTION_ARGS)
Definition: btree_time.c:332
bool gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b, const gbtree_ninfo *tinfo)
bool leafkey
Definition: gist.h:127
bool gbt_num_consistent(const GBT_NUMKEY_R *key, const void *query, const StrategyNumber *strategy, bool is_leaf, const gbtree_ninfo *tinfo)
static bool gbt_timele(const void *a, const void *b)
Definition: btree_time.c:74
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
uintptr_t Datum
Definition: postgres.h:374
Interval * abs_interval(Interval *a)
#define Max(x, y)
Definition: c.h:796
Datum gbt_time_penalty(PG_FUNCTION_ARGS)
Definition: btree_time.c:289
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:169
Datum gbt_time_distance(PG_FUNCTION_ARGS)
Definition: btree_time.c:229
#define INT64CONST(x)
Definition: c.h:307
#define PG_GETARG_TIMEADT(n)
Definition: date.h:83
static bool gbt_timegt(const void *a, const void *b)
Definition: btree_time.c:41
Datum gbt_time_same(PG_FUNCTION_ARGS)
Definition: btree_time.c:342
Datum gbt_time_consistent(PG_FUNCTION_ARGS)
Definition: btree_time.c:206
void * gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_ninfo *tinfo)
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:228
#define DatumGetPointer(X)
Definition: postgres.h:557
Datum gbt_time_union(PG_FUNCTION_ARGS)
Definition: btree_time.c:278
float8 TimeADT
Definition: date.h:27
void * palloc(Size size)
Definition: mcxt.c:891
Datum gbt_timetz_consistent(PG_FUNCTION_ARGS)
Definition: btree_time.c:247
Datum time_mi_time(PG_FUNCTION_ARGS)
Definition: date.c:1896
GIST_SPLITVEC * gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, const gbtree_ninfo *tinfo)
static bool gbt_timeeq(const void *a, const void *b)
Definition: btree_time.c:63
int i
#define PG_FUNCTION_ARGS
Definition: fmgr.h:150
Datum time_ge(PG_FUNCTION_ARGS)
Definition: date.c:1568
#define INTERVAL_TO_SEC(ivp)
Definition: date.h:30
OffsetNumber offset
Definition: gist.h:126
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:557
float8 gbt_num_distance(const GBT_NUMKEY_R *key, const void *query, bool is_leaf, const gbtree_ninfo *tinfo)
PG_FUNCTION_INFO_V1(gbt_time_compress)