Age Owner Branch data TLA Line data Source code
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 : : {
14 : : TimeADT lower;
15 : : TimeADT upper;
16 : : } timeKEY;
17 : :
18 : : /*
19 : : ** time ops
20 : : */
7261 teodor@sigaev.ru 21 :CBC 2 : PG_FUNCTION_INFO_V1(gbt_time_compress);
22 : 2 : PG_FUNCTION_INFO_V1(gbt_timetz_compress);
3306 heikki.linnakangas@i 23 : 2 : PG_FUNCTION_INFO_V1(gbt_time_fetch);
7261 teodor@sigaev.ru 24 : 3 : PG_FUNCTION_INFO_V1(gbt_time_union);
25 : 3 : PG_FUNCTION_INFO_V1(gbt_time_picksplit);
26 : 2 : PG_FUNCTION_INFO_V1(gbt_time_consistent);
4792 tgl@sss.pgh.pa.us 27 : 2 : PG_FUNCTION_INFO_V1(gbt_time_distance);
7261 teodor@sigaev.ru 28 : 2 : PG_FUNCTION_INFO_V1(gbt_timetz_consistent);
29 : 3 : PG_FUNCTION_INFO_V1(gbt_time_penalty);
30 : 3 : PG_FUNCTION_INFO_V1(gbt_time_same);
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
2581 andrew@dunslane.net 41 : 3179 : gbt_timegt(const void *a, const void *b, FmgrInfo *flinfo)
42 : : {
5837 tgl@sss.pgh.pa.us 43 : 3179 : const TimeADT *aa = (const TimeADT *) a;
44 : 3179 : const TimeADT *bb = (const TimeADT *) b;
45 : :
46 : 3179 : return DatumGetBool(DirectFunctionCall2(time_gt,
47 : : TimeADTGetDatumFast(*aa),
48 : : TimeADTGetDatumFast(*bb)));
49 : : }
50 : :
51 : : static bool
2581 andrew@dunslane.net 52 : 1199 : gbt_timege(const void *a, const void *b, FmgrInfo *flinfo)
53 : : {
5837 tgl@sss.pgh.pa.us 54 : 1199 : const TimeADT *aa = (const TimeADT *) a;
55 : 1199 : const TimeADT *bb = (const TimeADT *) b;
56 : :
57 : 1199 : return DatumGetBool(DirectFunctionCall2(time_ge,
58 : : TimeADTGetDatumFast(*aa),
59 : : TimeADTGetDatumFast(*bb)));
60 : : }
61 : :
62 : : static bool
2581 andrew@dunslane.net 63 : 1853 : gbt_timeeq(const void *a, const void *b, FmgrInfo *flinfo)
64 : : {
5837 tgl@sss.pgh.pa.us 65 : 1853 : const TimeADT *aa = (const TimeADT *) a;
66 : 1853 : const TimeADT *bb = (const TimeADT *) b;
67 : :
68 : 1853 : return DatumGetBool(DirectFunctionCall2(time_eq,
69 : : TimeADTGetDatumFast(*aa),
70 : : TimeADTGetDatumFast(*bb)));
71 : : }
72 : :
73 : : static bool
2581 andrew@dunslane.net 74 : 1919 : gbt_timele(const void *a, const void *b, FmgrInfo *flinfo)
75 : : {
5837 tgl@sss.pgh.pa.us 76 : 1919 : const TimeADT *aa = (const TimeADT *) a;
77 : 1919 : const TimeADT *bb = (const TimeADT *) b;
78 : :
79 : 1919 : return DatumGetBool(DirectFunctionCall2(time_le,
80 : : TimeADTGetDatumFast(*aa),
81 : : TimeADTGetDatumFast(*bb)));
82 : : }
83 : :
84 : : static bool
2581 andrew@dunslane.net 85 : 3846 : gbt_timelt(const void *a, const void *b, FmgrInfo *flinfo)
86 : : {
5837 tgl@sss.pgh.pa.us 87 : 3846 : const TimeADT *aa = (const TimeADT *) a;
88 : 3846 : const TimeADT *bb = (const TimeADT *) b;
89 : :
90 : 3846 : return DatumGetBool(DirectFunctionCall2(time_lt,
91 : : TimeADTGetDatumFast(*aa),
92 : : TimeADTGetDatumFast(*bb)));
93 : : }
94 : :
95 : :
96 : :
97 : : static int
2581 andrew@dunslane.net 98 : 9061 : gbt_timekey_cmp(const void *a, const void *b, FmgrInfo *flinfo)
99 : : {
4599 peter_e@gmx.net 100 : 9061 : timeKEY *ia = (timeKEY *) (((const Nsrt *) a)->t);
101 : 9061 : timeKEY *ib = (timeKEY *) (((const Nsrt *) b)->t);
102 : : int res;
103 : :
5247 teodor@sigaev.ru 104 : 9061 : res = DatumGetInt32(DirectFunctionCall2(time_cmp, TimeADTGetDatumFast(ia->lower), TimeADTGetDatumFast(ib->lower)));
105 [ - + ]: 9061 : if (res == 0)
5247 teodor@sigaev.ru 106 :UBC 0 : return DatumGetInt32(DirectFunctionCall2(time_cmp, TimeADTGetDatumFast(ia->upper), TimeADTGetDatumFast(ib->upper)));
107 : :
5247 teodor@sigaev.ru 108 :CBC 9061 : return res;
109 : : }
110 : :
111 : : static float8
2581 andrew@dunslane.net 112 : 144 : gbt_time_dist(const void *a, const void *b, FmgrInfo *flinfo)
113 : : {
4792 tgl@sss.pgh.pa.us 114 : 144 : const TimeADT *aa = (const TimeADT *) a;
115 : 144 : const TimeADT *bb = (const TimeADT *) b;
116 : : Interval *i;
117 : :
118 : 144 : i = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
119 : : TimeADTGetDatumFast(*aa),
120 : : TimeADTGetDatumFast(*bb)));
555 peter@eisentraut.org 121 : 144 : return fabs(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,
135 : : gbt_timekey_cmp,
136 : : gbt_time_dist
137 : : };
138 : :
139 : :
4792 tgl@sss.pgh.pa.us 140 : 2 : PG_FUNCTION_INFO_V1(time_dist);
141 : : Datum
142 : 547 : time_dist(PG_FUNCTION_ARGS)
143 : : {
144 : 547 : Datum diff = DirectFunctionCall2(time_mi_time,
145 : : PG_GETARG_DATUM(0),
146 : : PG_GETARG_DATUM(1));
147 : :
148 : 547 : PG_RETURN_INTERVAL_P(abs_interval(DatumGetIntervalP(diff)));
149 : : }
150 : :
151 : :
152 : : /**************************************************
153 : : * time ops
154 : : **************************************************/
155 : :
156 : :
157 : :
158 : : Datum
7261 teodor@sigaev.ru 159 : 553 : gbt_time_compress(PG_FUNCTION_ARGS)
160 : : {
7168 bruce@momjian.us 161 : 553 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
162 : :
3307 heikki.linnakangas@i 163 : 553 : PG_RETURN_POINTER(gbt_num_compress(entry, &tinfo));
164 : : }
165 : :
166 : :
167 : : Datum
7261 teodor@sigaev.ru 168 : 538 : gbt_timetz_compress(PG_FUNCTION_ARGS)
169 : : {
7168 bruce@momjian.us 170 : 538 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
171 : : GISTENTRY *retval;
172 : :
173 [ + + ]: 538 : if (entry->leafkey)
174 : : {
175 : 531 : timeKEY *r = (timeKEY *) palloc(sizeof(timeKEY));
176 : 531 : TimeTzADT *tz = DatumGetTimeTzADTP(entry->key);
177 : : TimeADT tmp;
178 : :
179 : 531 : retval = palloc(sizeof(GISTENTRY));
180 : :
181 : : /* We are using the time + zone only to compress */
6929 tgl@sss.pgh.pa.us 182 : 531 : tmp = tz->time + (tz->zone * INT64CONST(1000000));
183 : 531 : r->lower = r->upper = tmp;
7168 bruce@momjian.us 184 : 531 : gistentryinit(*retval, PointerGetDatum(r),
185 : : entry->rel, entry->page,
186 : : entry->offset, false);
187 : : }
188 : : else
189 : 7 : retval = entry;
190 : 538 : PG_RETURN_POINTER(retval);
191 : : }
192 : :
193 : : Datum
3306 heikki.linnakangas@i 194 : 142 : gbt_time_fetch(PG_FUNCTION_ARGS)
195 : : {
196 : 142 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
197 : :
198 : 142 : PG_RETURN_POINTER(gbt_num_fetch(entry, &tinfo));
199 : : }
200 : :
201 : : Datum
7261 teodor@sigaev.ru 202 : 1529 : gbt_time_consistent(PG_FUNCTION_ARGS)
203 : : {
7168 bruce@momjian.us 204 : 1529 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
205 : 1529 : TimeADT query = PG_GETARG_TIMEADT(1);
5844 tgl@sss.pgh.pa.us 206 : 1529 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
207 : :
208 : : /* Oid subtype = PG_GETARG_OID(3); */
209 : 1529 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
7168 bruce@momjian.us 210 : 1529 : timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
211 : : GBT_NUMKEY_R key;
212 : :
213 : : /* All cases served by this function are exact */
5844 tgl@sss.pgh.pa.us 214 : 1529 : *recheck = false;
215 : :
5421 bruce@momjian.us 216 : 1529 : key.lower = (GBT_NUMKEY *) &kkk->lower;
217 : 1529 : key.upper = (GBT_NUMKEY *) &kkk->upper;
218 : :
1536 alvherre@alvh.no-ip. 219 : 1529 : PG_RETURN_BOOL(gbt_num_consistent(&key, (void *) &query, &strategy,
220 : : GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
221 : : }
222 : :
223 : : Datum
4792 tgl@sss.pgh.pa.us 224 : 145 : gbt_time_distance(PG_FUNCTION_ARGS)
225 : : {
226 : 145 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
227 : 145 : TimeADT query = PG_GETARG_TIMEADT(1);
228 : :
229 : : /* Oid subtype = PG_GETARG_OID(3); */
230 : 145 : timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
231 : : GBT_NUMKEY_R key;
232 : :
233 : 145 : key.lower = (GBT_NUMKEY *) &kkk->lower;
234 : 145 : key.upper = (GBT_NUMKEY *) &kkk->upper;
235 : :
1536 alvherre@alvh.no-ip. 236 : 145 : PG_RETURN_FLOAT8(gbt_num_distance(&key, (void *) &query, GIST_LEAF(entry),
237 : : &tinfo, fcinfo->flinfo));
238 : : }
239 : :
240 : : Datum
7261 teodor@sigaev.ru 241 : 4791 : gbt_timetz_consistent(PG_FUNCTION_ARGS)
242 : : {
7168 bruce@momjian.us 243 : 4791 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
244 : 4791 : TimeTzADT *query = PG_GETARG_TIMETZADT_P(1);
6929 tgl@sss.pgh.pa.us 245 : 4791 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
246 : :
247 : : /* Oid subtype = PG_GETARG_OID(3); */
5844 248 : 4791 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
7168 bruce@momjian.us 249 : 4791 : timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
250 : : TimeADT qqq;
251 : : GBT_NUMKEY_R key;
252 : :
253 : : /* All cases served by this function are inexact */
5844 tgl@sss.pgh.pa.us 254 : 4791 : *recheck = true;
255 : :
6929 256 : 4791 : qqq = query->time + (query->zone * INT64CONST(1000000));
257 : :
5421 bruce@momjian.us 258 : 4791 : key.lower = (GBT_NUMKEY *) &kkk->lower;
259 : 4791 : key.upper = (GBT_NUMKEY *) &kkk->upper;
260 : :
1536 alvherre@alvh.no-ip. 261 : 4791 : PG_RETURN_BOOL(gbt_num_consistent(&key, (void *) &qqq, &strategy,
262 : : GIST_LEAF(entry), &tinfo, fcinfo->flinfo));
263 : : }
264 : :
265 : :
266 : : Datum
7261 teodor@sigaev.ru 267 : 599 : gbt_time_union(PG_FUNCTION_ARGS)
268 : : {
7168 bruce@momjian.us 269 : 599 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
270 : 599 : void *out = palloc(sizeof(timeKEY));
271 : :
272 : 599 : *(int *) PG_GETARG_POINTER(1) = sizeof(timeKEY);
2581 andrew@dunslane.net 273 : 599 : PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo, fcinfo->flinfo));
274 : : }
275 : :
276 : :
277 : : Datum
7261 teodor@sigaev.ru 278 : 1045 : gbt_time_penalty(PG_FUNCTION_ARGS)
279 : : {
7168 bruce@momjian.us 280 : 1045 : timeKEY *origentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
281 : 1045 : timeKEY *newentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
282 : 1045 : float *result = (float *) PG_GETARG_POINTER(2);
283 : : Interval *intr;
284 : : double res;
285 : : double res2;
286 : :
1536 alvherre@alvh.no-ip. 287 : 1045 : intr = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
288 : : TimeADTGetDatumFast(newentry->upper),
289 : : TimeADTGetDatumFast(origentry->upper)));
6842 tgl@sss.pgh.pa.us 290 : 1045 : res = INTERVAL_TO_SEC(intr);
291 [ + + ]: 1045 : res = Max(res, 0);
292 : :
1536 alvherre@alvh.no-ip. 293 : 1045 : intr = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
294 : : TimeADTGetDatumFast(origentry->lower),
295 : : TimeADTGetDatumFast(newentry->lower)));
6842 tgl@sss.pgh.pa.us 296 : 1045 : res2 = INTERVAL_TO_SEC(intr);
297 [ + + ]: 1045 : res2 = Max(res2, 0);
298 : :
299 : 1045 : res += res2;
300 : :
7168 bruce@momjian.us 301 : 1045 : *result = 0.0;
302 : :
303 [ + + ]: 1045 : if (res > 0)
304 : : {
1536 alvherre@alvh.no-ip. 305 : 454 : intr = DatumGetIntervalP(DirectFunctionCall2(time_mi_time,
306 : : TimeADTGetDatumFast(origentry->upper),
307 : : TimeADTGetDatumFast(origentry->lower)));
7168 bruce@momjian.us 308 : 454 : *result += FLT_MIN;
6842 tgl@sss.pgh.pa.us 309 : 454 : *result += (float) (res / (res + INTERVAL_TO_SEC(intr)));
7168 bruce@momjian.us 310 : 454 : *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
311 : : }
312 : :
313 : 1045 : PG_RETURN_POINTER(result);
314 : : }
315 : :
316 : :
317 : : Datum
7261 teodor@sigaev.ru 318 : 4 : gbt_time_picksplit(PG_FUNCTION_ARGS)
319 : : {
1536 alvherre@alvh.no-ip. 320 : 4 : PG_RETURN_POINTER(gbt_num_picksplit((GistEntryVector *) PG_GETARG_POINTER(0),
321 : : (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
322 : : &tinfo, fcinfo->flinfo));
323 : : }
324 : :
325 : : Datum
7261 teodor@sigaev.ru 326 : 597 : gbt_time_same(PG_FUNCTION_ARGS)
327 : : {
7168 bruce@momjian.us 328 : 597 : timeKEY *b1 = (timeKEY *) PG_GETARG_POINTER(0);
329 : 597 : timeKEY *b2 = (timeKEY *) PG_GETARG_POINTER(1);
330 : 597 : bool *result = (bool *) PG_GETARG_POINTER(2);
331 : :
2581 andrew@dunslane.net 332 : 597 : *result = gbt_num_same((void *) b1, (void *) b2, &tinfo, fcinfo->flinfo);
7168 bruce@momjian.us 333 : 597 : PG_RETURN_POINTER(result);
334 : : }
|