Fix xslt_process() to ensure that it inserts a NULL terminator after the
[PostgreSQL.git] / contrib / btree_gist / btree_time.c
blob42e78b8024abbe31e59c242a4e283ae60ce1c96c
1 /*
2 * $PostgreSQL$
3 */
4 #include "btree_gist.h"
5 #include "btree_utils_num.h"
6 #include "utils/date.h"
7 #include "utils/timestamp.h"
9 typedef struct
11 TimeADT lower;
12 TimeADT upper;
13 } timeKEY;
16 ** time ops
18 PG_FUNCTION_INFO_V1(gbt_time_compress);
19 PG_FUNCTION_INFO_V1(gbt_timetz_compress);
20 PG_FUNCTION_INFO_V1(gbt_time_union);
21 PG_FUNCTION_INFO_V1(gbt_time_picksplit);
22 PG_FUNCTION_INFO_V1(gbt_time_consistent);
23 PG_FUNCTION_INFO_V1(gbt_timetz_consistent);
24 PG_FUNCTION_INFO_V1(gbt_time_penalty);
25 PG_FUNCTION_INFO_V1(gbt_time_same);
27 Datum gbt_time_compress(PG_FUNCTION_ARGS);
28 Datum gbt_timetz_compress(PG_FUNCTION_ARGS);
29 Datum gbt_time_union(PG_FUNCTION_ARGS);
30 Datum gbt_time_picksplit(PG_FUNCTION_ARGS);
31 Datum gbt_time_consistent(PG_FUNCTION_ARGS);
32 Datum gbt_timetz_consistent(PG_FUNCTION_ARGS);
33 Datum gbt_time_penalty(PG_FUNCTION_ARGS);
34 Datum gbt_time_same(PG_FUNCTION_ARGS);
37 #ifdef USE_FLOAT8_BYVAL
38 #define TimeADTGetDatumFast(X) TimeADTGetDatum(X)
39 #else
40 #define TimeADTGetDatumFast(X) PointerGetDatum(&(X))
41 #endif
44 static bool
45 gbt_timegt(const void *a, const void *b)
47 const TimeADT *aa = (const TimeADT *) a;
48 const TimeADT *bb = (const TimeADT *) b;
50 return DatumGetBool(DirectFunctionCall2(time_gt,
51 TimeADTGetDatumFast(*aa),
52 TimeADTGetDatumFast(*bb)));
55 static bool
56 gbt_timege(const void *a, const void *b)
58 const TimeADT *aa = (const TimeADT *) a;
59 const TimeADT *bb = (const TimeADT *) b;
61 return DatumGetBool(DirectFunctionCall2(time_ge,
62 TimeADTGetDatumFast(*aa),
63 TimeADTGetDatumFast(*bb)));
66 static bool
67 gbt_timeeq(const void *a, const void *b)
69 const TimeADT *aa = (const TimeADT *) a;
70 const TimeADT *bb = (const TimeADT *) b;
72 return DatumGetBool(DirectFunctionCall2(time_eq,
73 TimeADTGetDatumFast(*aa),
74 TimeADTGetDatumFast(*bb)));
77 static bool
78 gbt_timele(const void *a, const void *b)
80 const TimeADT *aa = (const TimeADT *) a;
81 const TimeADT *bb = (const TimeADT *) b;
83 return DatumGetBool(DirectFunctionCall2(time_le,
84 TimeADTGetDatumFast(*aa),
85 TimeADTGetDatumFast(*bb)));
88 static bool
89 gbt_timelt(const void *a, const void *b)
91 const TimeADT *aa = (const TimeADT *) a;
92 const TimeADT *bb = (const TimeADT *) b;
94 return DatumGetBool(DirectFunctionCall2(time_lt,
95 TimeADTGetDatumFast(*aa),
96 TimeADTGetDatumFast(*bb)));
101 static int
102 gbt_timekey_cmp(const void *a, const void *b)
104 if (gbt_timegt((void *) &(((Nsrt *) a)->t[0]), (void *) &(((Nsrt *) b)->t[0])))
105 return 1;
106 else if (gbt_timelt((void *) &(((Nsrt *) a)->t[0]), (void *) &(((Nsrt *) b)->t[0])))
107 return -1;
108 return 0;
112 static const gbtree_ninfo tinfo =
114 gbt_t_time,
115 sizeof(TimeADT),
116 gbt_timegt,
117 gbt_timege,
118 gbt_timeeq,
119 gbt_timele,
120 gbt_timelt,
121 gbt_timekey_cmp
125 /**************************************************
126 * time ops
127 **************************************************/
131 Datum
132 gbt_time_compress(PG_FUNCTION_ARGS)
134 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
135 GISTENTRY *retval = NULL;
137 PG_RETURN_POINTER(gbt_num_compress(retval, entry, &tinfo));
141 Datum
142 gbt_timetz_compress(PG_FUNCTION_ARGS)
144 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
145 GISTENTRY *retval;
147 if (entry->leafkey)
149 timeKEY *r = (timeKEY *) palloc(sizeof(timeKEY));
150 TimeTzADT *tz = DatumGetTimeTzADTP(entry->key);
151 TimeADT tmp;
153 retval = palloc(sizeof(GISTENTRY));
155 /* We are using the time + zone only to compress */
156 #ifdef HAVE_INT64_TIMESTAMP
157 tmp = tz->time + (tz->zone * INT64CONST(1000000));
158 #else
159 tmp = (tz->time + tz->zone);
160 #endif
161 r->lower = r->upper = tmp;
162 gistentryinit(*retval, PointerGetDatum(r),
163 entry->rel, entry->page,
164 entry->offset, FALSE);
166 else
167 retval = entry;
168 PG_RETURN_POINTER(retval);
172 Datum
173 gbt_time_consistent(PG_FUNCTION_ARGS)
175 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
176 TimeADT query = PG_GETARG_TIMEADT(1);
177 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
179 /* Oid subtype = PG_GETARG_OID(3); */
180 bool *recheck = (bool *) PG_GETARG_POINTER(4);
181 timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
182 GBT_NUMKEY_R key;
184 /* All cases served by this function are exact */
185 *recheck = false;
187 key.lower = (GBT_NUMKEY *) &kkk->lower;
188 key.upper = (GBT_NUMKEY *) &kkk->upper;
190 PG_RETURN_BOOL(
191 gbt_num_consistent(&key, (void *) &query, &strategy, GIST_LEAF(entry), &tinfo)
195 Datum
196 gbt_timetz_consistent(PG_FUNCTION_ARGS)
198 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
199 TimeTzADT *query = PG_GETARG_TIMETZADT_P(1);
200 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
202 /* Oid subtype = PG_GETARG_OID(3); */
203 bool *recheck = (bool *) PG_GETARG_POINTER(4);
204 timeKEY *kkk = (timeKEY *) DatumGetPointer(entry->key);
205 TimeADT qqq;
206 GBT_NUMKEY_R key;
208 /* All cases served by this function are inexact */
209 *recheck = true;
211 #ifdef HAVE_INT64_TIMESTAMP
212 qqq = query->time + (query->zone * INT64CONST(1000000));
213 #else
214 qqq = (query->time + query->zone);
215 #endif
217 key.lower = (GBT_NUMKEY *) &kkk->lower;
218 key.upper = (GBT_NUMKEY *) &kkk->upper;
220 PG_RETURN_BOOL(
221 gbt_num_consistent(&key, (void *) &qqq, &strategy, GIST_LEAF(entry), &tinfo)
226 Datum
227 gbt_time_union(PG_FUNCTION_ARGS)
229 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
230 void *out = palloc(sizeof(timeKEY));
232 *(int *) PG_GETARG_POINTER(1) = sizeof(timeKEY);
233 PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
237 Datum
238 gbt_time_penalty(PG_FUNCTION_ARGS)
240 timeKEY *origentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
241 timeKEY *newentry = (timeKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
242 float *result = (float *) PG_GETARG_POINTER(2);
243 Interval *intr;
244 double res;
245 double res2;
247 intr = DatumGetIntervalP(DirectFunctionCall2(
248 time_mi_time,
249 TimeADTGetDatumFast(newentry->upper),
250 TimeADTGetDatumFast(origentry->upper)));
251 res = INTERVAL_TO_SEC(intr);
252 res = Max(res, 0);
254 intr = DatumGetIntervalP(DirectFunctionCall2(
255 time_mi_time,
256 TimeADTGetDatumFast(origentry->lower),
257 TimeADTGetDatumFast(newentry->lower)));
258 res2 = INTERVAL_TO_SEC(intr);
259 res2 = Max(res2, 0);
261 res += res2;
263 *result = 0.0;
265 if (res > 0)
267 intr = DatumGetIntervalP(DirectFunctionCall2(
268 time_mi_time,
269 TimeADTGetDatumFast(origentry->upper),
270 TimeADTGetDatumFast(origentry->lower)));
271 *result += FLT_MIN;
272 *result += (float) (res / (res + INTERVAL_TO_SEC(intr)));
273 *result *= (FLT_MAX / (((GISTENTRY *) PG_GETARG_POINTER(0))->rel->rd_att->natts + 1));
276 PG_RETURN_POINTER(result);
280 Datum
281 gbt_time_picksplit(PG_FUNCTION_ARGS)
283 PG_RETURN_POINTER(gbt_num_picksplit(
284 (GistEntryVector *) PG_GETARG_POINTER(0),
285 (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
286 &tinfo
290 Datum
291 gbt_time_same(PG_FUNCTION_ARGS)
293 timeKEY *b1 = (timeKEY *) PG_GETARG_POINTER(0);
294 timeKEY *b2 = (timeKEY *) PG_GETARG_POINTER(1);
295 bool *result = (bool *) PG_GETARG_POINTER(2);
297 *result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
298 PG_RETURN_POINTER(result);