2 * contrib/btree_gist/btree_utils_num.c
4 #include "btree_gist.h"
5 #include "btree_utils_num.h"
6 #include "utils/cash.h"
7 #include "utils/date.h"
11 gbt_num_compress(GISTENTRY *retval, GISTENTRY *entry, const gbtree_ninfo *tinfo)
28 GBT_NUMKEY *r = (GBT_NUMKEY *) palloc0(2 * tinfo->size);
34 v.i2 = DatumGetInt16(entry->key);
38 v.i4 = DatumGetInt32(entry->key);
42 v.i8 = DatumGetInt64(entry->key);
46 v.i4 = DatumGetObjectId(entry->key);
50 v.f4 = DatumGetFloat4(entry->key);
54 v.f8 = DatumGetFloat8(entry->key);
58 v.dt = DatumGetDateADT(entry->key);
62 v.tm = DatumGetTimeADT(entry->key);
66 v.ts = DatumGetTimestamp(entry->key);
70 v.ch = DatumGetCash(entry->key);
74 leaf = DatumGetPointer(entry->key);
77 memcpy((void *) &r[0], leaf, tinfo->size);
78 memcpy((void *) &r[tinfo->size], leaf, tinfo->size);
79 retval = palloc(sizeof(GISTENTRY));
80 gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page,
81 entry->offset, FALSE);
93 ** The GiST union method for numerical values
97 gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_ninfo *tinfo)
105 numranges = entryvec->n;
106 cur = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[0].key));
109 o.lower = &((GBT_NUMKEY *) out)[0];
110 o.upper = &((GBT_NUMKEY *) out)[tinfo->size];
112 memcpy((void *) out, (void *) cur, 2 * tinfo->size);
114 for (i = 1; i < numranges; i++)
116 cur = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[i].key));
118 c.upper = &cur[tinfo->size];
119 if ((*tinfo->f_gt) (o.lower, c.lower)) /* out->lower > cur->lower */
120 memcpy((void *) o.lower, (void *) c.lower, tinfo->size);
121 if ((*tinfo->f_lt) (o.upper, c.upper)) /* out->upper < cur->upper */
122 memcpy((void *) o.upper, (void *) c.upper, tinfo->size);
131 ** The GiST same method for numerical values
135 gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b, const gbtree_ninfo *tinfo)
141 b1.lower = &(((GBT_NUMKEY *) a)[0]);
142 b1.upper = &(((GBT_NUMKEY *) a)[tinfo->size]);
143 b2.lower = &(((GBT_NUMKEY *) b)[0]);
144 b2.upper = &(((GBT_NUMKEY *) b)[tinfo->size]);
147 (*tinfo->f_eq) (b1.lower, b2.lower) &&
148 (*tinfo->f_eq) (b1.upper, b2.upper)
157 gbt_num_bin_union(Datum *u, GBT_NUMKEY *e, const gbtree_ninfo *tinfo)
163 rd.upper = &e[tinfo->size];
165 if (!DatumGetPointer(*u))
167 *u = PointerGetDatum(palloc(2 * tinfo->size));
168 memcpy((void *) &(((GBT_NUMKEY *) DatumGetPointer(*u))[0]), (void *) rd.lower, tinfo->size);
169 memcpy((void *) &(((GBT_NUMKEY *) DatumGetPointer(*u))[tinfo->size]), (void *) rd.upper, tinfo->size);
175 ur.lower = &(((GBT_NUMKEY *) DatumGetPointer(*u))[0]);
176 ur.upper = &(((GBT_NUMKEY *) DatumGetPointer(*u))[tinfo->size]);
177 if ((*tinfo->f_gt) ((void *) ur.lower, (void *) rd.lower))
178 memcpy((void *) ur.lower, (void *) rd.lower, tinfo->size);
179 if ((*tinfo->f_lt) ((void *) ur.upper, (void *) rd.upper))
180 memcpy((void *) ur.upper, (void *) rd.upper, tinfo->size);
187 ** The GiST consistent method
192 const GBT_NUMKEY_R *key,
194 const StrategyNumber *strategy,
196 const gbtree_ninfo *tinfo
204 case BTLessEqualStrategyNumber:
205 retval = (*tinfo->f_ge) (query, key->lower);
207 case BTLessStrategyNumber:
209 retval = (*tinfo->f_gt) (query, key->lower);
211 retval = (*tinfo->f_ge) (query, key->lower);
213 case BTEqualStrategyNumber:
215 retval = (*tinfo->f_eq) (query, key->lower);
217 retval = (*tinfo->f_le) (key->lower, query) && (*tinfo->f_le) (query, key->upper);
219 case BTGreaterStrategyNumber:
221 retval = (*tinfo->f_lt) (query, key->upper);
223 retval = (*tinfo->f_le) (query, key->upper);
225 case BTGreaterEqualStrategyNumber:
226 retval = (*tinfo->f_le) (query, key->upper);
228 case BtreeGistNotEqualStrategyNumber:
229 retval = ! ((*tinfo->f_eq) (query, key->lower) &&
230 (*tinfo->f_eq) (query, key->upper));
241 gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v,
242 const gbtree_ninfo *tinfo)
245 maxoff = entryvec->n - 1;
249 arr = (Nsrt *) palloc((maxoff + 1) * sizeof(Nsrt));
250 nbytes = (maxoff + 2) * sizeof(OffsetNumber);
251 v->spl_left = (OffsetNumber *) palloc(nbytes);
252 v->spl_right = (OffsetNumber *) palloc(nbytes);
253 v->spl_ldatum = PointerGetDatum(0);
254 v->spl_rdatum = PointerGetDatum(0);
260 for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
262 arr[i].t = (GBT_NUMKEY *) DatumGetPointer((entryvec->vector[i].key));
265 qsort((void *) &arr[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1, sizeof(Nsrt), tinfo->f_cmp);
267 /* We do simply create two parts */
269 for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
271 if (i <= (maxoff - FirstOffsetNumber + 1) / 2)
273 gbt_num_bin_union(&v->spl_ldatum, arr[i].t, tinfo);
274 v->spl_left[v->spl_nleft] = arr[i].i;
279 gbt_num_bin_union(&v->spl_rdatum, arr[i].t, tinfo);
280 v->spl_right[v->spl_nright] = arr[i].i;