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);
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 
219  PG_RETURN_BOOL(gbt_num_consistent(&key, (void *) &query, &strategy,
220  GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
221 }
222 
223 Datum
225 {
226  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
227  TimeADT query = PG_GETARG_TIMEADT(1);
228 
229  /* Oid subtype = PG_GETARG_OID(3); */
230  timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
232 
233  key.lower = (GBT_NUMKEY *) &kkk->lower;
234  key.upper = (GBT_NUMKEY *) &kkk->upper;
235 
236  PG_RETURN_FLOAT8(gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry),
237  &tinfo, fcinfo->flinfo));
238 }
239 
240 Datum
242 {
243  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
244  TimeTzADT *query = PG_GETARG_TIMETZADT_P(1);
246 
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;
252 
253  /* All cases served by this function are inexact */
254  *recheck = true;
255 
256  qqq = query->time + (query->zone * INT64CONST(1000000));
257 
258  key.lower = (GBT_NUMKEY *) &kkk->lower;
259  key.upper = (GBT_NUMKEY *) &kkk->upper;
260 
261  PG_RETURN_BOOL(gbt_num_consistent(&key, (void *) &qqq, &strategy,
262  GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
263 }
264 
265 
266 Datum
268 {
270  void *out = palloc(sizeof(timeKEY));
271 
272  *(int *) PG_GETARG_POINTER(1) = sizeof(timeKEY);
273  PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
274 }
275 
276 
277 Datum
279 {
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;
286 
288  TimeADTGetDatumFast(newentry->upper),
289  TimeADTGetDatumFast(origentry->upper)));
290  res = INTERVAL_TO_SEC(intr);
291  res = Max(res, 0);
292 
294  TimeADTGetDatumFast(origentry->lower),
295  TimeADTGetDatumFast(newentry->lower)));
296  res2 = INTERVAL_TO_SEC(intr);
297  res2 = Max(res2, 0);
298 
299  res += res2;
300 
301  *result = 0.0;
302 
303  if (res > 0)
304  {
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));
311  }
312 
313  PG_RETURN_POINTER(result);
314 }
315 
316 
317 Datum
319 {
322  &tinfo, fcinfo->flinfo));
323 }
324 
325 Datum
327 {
328  timeKEY *b1 = (timeKEY *) PG_GETARG_POINTER(0);
329  timeKEY *b2 = (timeKEY *) PG_GETARG_POINTER(1);
330  bool *result = (bool *) PG_GETARG_POINTER(2);
331 
332  *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
333  PG_RETURN_POINTER(result);
334 }
#define GIST_LEAF(entry)
Definition: gist.h:162
Datum gbt_timetz_compress(PG_FUNCTION_ARGS)
Definition: btree_time.c:168
Relation rel
Definition: gist.h:153
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:360
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:29
#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:472
GISTENTRY * gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo)
#define PointerGetDatum(X)
Definition: postgres.h:556
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
Datum time_le(PG_FUNCTION_ARGS)
Definition: date.c:1560
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:55
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:365
Datum time_eq(PG_FUNCTION_ARGS)
Definition: date.c:1533
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:276
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:154
#define Abs(x)
Definition: c.h:933
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:498
Datum time_lt(PG_FUNCTION_ARGS)
Definition: date.c:1551
Datum time_cmp(PG_FUNCTION_ARGS)
Definition: date.c:1587
int32 zone
Definition: date.h:30
TimeADT upper
Definition: btree_time.c:15
Datum time_gt(PG_FUNCTION_ARGS)
Definition: date.c:1569
Datum key
Definition: gist.h:152
char GBT_NUMKEY
#define PG_GETARG_TIMETZADT_P(n)
Definition: date.h:63
#define DatumGetBool(X)
Definition: postgres.h:393
static bool gbt_timegt(const void *a, const void *b, FmgrInfo *flinfo)
Definition: btree_time.c:41
int64 TimeADT
Definition: date.h:25
Datum gbt_time_picksplit(PG_FUNCTION_ARGS)
Definition: btree_time.c:318
bool leafkey
Definition: gist.h:156
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
uintptr_t Datum
Definition: postgres.h:367
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:921
Datum gbt_time_penalty(PG_FUNCTION_ARGS)
Definition: btree_time.c:278
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:236
Datum gbt_time_distance(PG_FUNCTION_ARGS)
Definition: btree_time.c:224
#define PG_GETARG_TIMEADT(n)
Definition: date.h:62
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:326
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:272
#define DatumGetPointer(X)
Definition: postgres.h:549
Datum gbt_time_union(PG_FUNCTION_ARGS)
Definition: btree_time.c:267
void * palloc(Size size)
Definition: mcxt.c:950
Datum gbt_timetz_consistent(PG_FUNCTION_ARGS)
Definition: btree_time.c:241
Datum time_mi_time(PG_FUNCTION_ARGS)
Definition: date.c:1890
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:193
Datum time_ge(PG_FUNCTION_ARGS)
Definition: date.c:1578
#define INTERVAL_TO_SEC(ivp)
Definition: date.h:27
OffsetNumber offset
Definition: gist.h:155
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:626
PG_FUNCTION_INFO_V1(gbt_time_compress)
void * gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_ninfo *tinfo, FmgrInfo *flinfo)