Fix xslt_process() to ensure that it inserts a NULL terminator after the
[PostgreSQL.git] / contrib / btree_gist / btree_interval.c
blob6f7b4bc52e7fc80c110dfe491b244e17953a5119
1 /*
2 * $PostgreSQL$
3 */
4 #include "btree_gist.h"
5 #include "btree_utils_num.h"
6 #include "utils/timestamp.h"
8 typedef struct
10 Interval lower,
11 upper;
12 } intvKEY;
16 ** Interval ops
18 PG_FUNCTION_INFO_V1(gbt_intv_compress);
19 PG_FUNCTION_INFO_V1(gbt_intv_decompress);
20 PG_FUNCTION_INFO_V1(gbt_intv_union);
21 PG_FUNCTION_INFO_V1(gbt_intv_picksplit);
22 PG_FUNCTION_INFO_V1(gbt_intv_consistent);
23 PG_FUNCTION_INFO_V1(gbt_intv_penalty);
24 PG_FUNCTION_INFO_V1(gbt_intv_same);
26 Datum gbt_intv_compress(PG_FUNCTION_ARGS);
27 Datum gbt_intv_decompress(PG_FUNCTION_ARGS);
28 Datum gbt_intv_union(PG_FUNCTION_ARGS);
29 Datum gbt_intv_picksplit(PG_FUNCTION_ARGS);
30 Datum gbt_intv_consistent(PG_FUNCTION_ARGS);
31 Datum gbt_intv_penalty(PG_FUNCTION_ARGS);
32 Datum gbt_intv_same(PG_FUNCTION_ARGS);
35 static bool
36 gbt_intvgt(const void *a, const void *b)
38 return DatumGetBool(DirectFunctionCall2(interval_gt, IntervalPGetDatum(a), IntervalPGetDatum(b)));
41 static bool
42 gbt_intvge(const void *a, const void *b)
44 return DatumGetBool(DirectFunctionCall2(interval_ge, IntervalPGetDatum(a), IntervalPGetDatum(b)));
47 static bool
48 gbt_intveq(const void *a, const void *b)
50 return DatumGetBool(DirectFunctionCall2(interval_eq, IntervalPGetDatum(a), IntervalPGetDatum(b)));
53 static bool
54 gbt_intvle(const void *a, const void *b)
56 return DatumGetBool(DirectFunctionCall2(interval_le, IntervalPGetDatum(a), IntervalPGetDatum(b)));
59 static bool
60 gbt_intvlt(const void *a, const void *b)
62 return DatumGetBool(DirectFunctionCall2(interval_lt, IntervalPGetDatum(a), IntervalPGetDatum(b)));
65 static int
66 gbt_intvkey_cmp(const void *a, const void *b)
68 return DatumGetInt32(
69 DirectFunctionCall2(interval_cmp,
70 IntervalPGetDatum(((Nsrt *) a)->t),
71 IntervalPGetDatum(((Nsrt *) b)->t)
77 static double
78 intr2num(const Interval *i)
80 return INTERVAL_TO_SEC(i);
84 * INTERVALSIZE should be the actual size-on-disk of an Interval, as shown
85 * in pg_type. This might be less than sizeof(Interval) if the compiler
86 * insists on adding alignment padding at the end of the struct.
88 #define INTERVALSIZE 16
90 static const gbtree_ninfo tinfo =
92 gbt_t_intv,
93 sizeof(Interval),
94 gbt_intvgt,
95 gbt_intvge,
96 gbt_intveq,
97 gbt_intvle,
98 gbt_intvlt,
99 gbt_intvkey_cmp
103 /**************************************************
104 * interval ops
105 **************************************************/
108 Datum
109 gbt_intv_compress(PG_FUNCTION_ARGS)
111 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
112 GISTENTRY *retval = entry;
114 if (entry->leafkey || INTERVALSIZE != sizeof(Interval))
116 char *r = (char *) palloc(2 * INTERVALSIZE);
118 retval = palloc(sizeof(GISTENTRY));
120 if (entry->leafkey)
122 Interval *key = DatumGetIntervalP(entry->key);
124 memcpy((void *) r, (void *) key, INTERVALSIZE);
125 memcpy((void *) (r + INTERVALSIZE), (void *) key, INTERVALSIZE);
127 else
129 intvKEY *key = (intvKEY *) DatumGetPointer(entry->key);
131 memcpy(r, &key->lower, INTERVALSIZE);
132 memcpy(r + INTERVALSIZE, &key->upper, INTERVALSIZE);
134 gistentryinit(*retval, PointerGetDatum(r),
135 entry->rel, entry->page,
136 entry->offset, FALSE);
139 PG_RETURN_POINTER(retval);
143 Datum
144 gbt_intv_decompress(PG_FUNCTION_ARGS)
146 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
147 GISTENTRY *retval = entry;
149 if (INTERVALSIZE != sizeof(Interval))
151 intvKEY *r = palloc(sizeof(intvKEY));
152 char *key = DatumGetPointer(entry->key);
154 retval = palloc(sizeof(GISTENTRY));
155 memcpy(&r->lower, key, INTERVALSIZE);
156 memcpy(&r->upper, key + INTERVALSIZE, INTERVALSIZE);
158 gistentryinit(*retval, PointerGetDatum(r),
159 entry->rel, entry->page,
160 entry->offset, FALSE);
162 PG_RETURN_POINTER(retval);
166 Datum
167 gbt_intv_consistent(PG_FUNCTION_ARGS)
169 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
170 Interval *query = PG_GETARG_INTERVAL_P(1);
171 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
173 /* Oid subtype = PG_GETARG_OID(3); */
174 bool *recheck = (bool *) PG_GETARG_POINTER(4);
175 intvKEY *kkk = (intvKEY *) DatumGetPointer(entry->key);
176 GBT_NUMKEY_R key;
178 /* All cases served by this function are exact */
179 *recheck = false;
181 key.lower = (GBT_NUMKEY *) &kkk->lower;
182 key.upper = (GBT_NUMKEY *) &kkk->upper;
184 PG_RETURN_BOOL(
185 gbt_num_consistent(&key, (void *) query, &strategy, GIST_LEAF(entry), &tinfo)
190 Datum
191 gbt_intv_union(PG_FUNCTION_ARGS)
193 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
194 void *out = palloc(sizeof(intvKEY));
196 *(int *) PG_GETARG_POINTER(1) = sizeof(intvKEY);
197 PG_RETURN_POINTER(gbt_num_union((void *) out, entryvec, &tinfo));
201 Datum
202 gbt_intv_penalty(PG_FUNCTION_ARGS)
204 intvKEY *origentry = (intvKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
205 intvKEY *newentry = (intvKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
206 float *result = (float *) PG_GETARG_POINTER(2);
207 double iorg[2],
208 inew[2];
210 iorg[0] = intr2num(&origentry->lower);
211 iorg[1] = intr2num(&origentry->upper);
212 inew[0] = intr2num(&newentry->lower);
213 inew[1] = intr2num(&newentry->upper);
215 penalty_num(result, iorg[0], iorg[1], inew[0], inew[1]);
217 PG_RETURN_POINTER(result);
221 Datum
222 gbt_intv_picksplit(PG_FUNCTION_ARGS)
224 PG_RETURN_POINTER(gbt_num_picksplit(
225 (GistEntryVector *) PG_GETARG_POINTER(0),
226 (GIST_SPLITVEC *) PG_GETARG_POINTER(1),
227 &tinfo
231 Datum
232 gbt_intv_same(PG_FUNCTION_ARGS)
234 intvKEY *b1 = (intvKEY *) PG_GETARG_POINTER(0);
235 intvKEY *b2 = (intvKEY *) PG_GETARG_POINTER(1);
236 bool *result = (bool *) PG_GETARG_POINTER(2);
238 *result = gbt_num_same((void *) b1, (void *) b2, &tinfo);
239 PG_RETURN_POINTER(result);