00001
00002
00003
00004
00005
00006 #include "postgres.h"
00007
00008 #include "access/gist.h"
00009 #include "access/nbtree.h"
00010 #include "access/skey.h"
00011 #include "utils/array.h"
00012 #include "crc32.h"
00013 #include "ltree.h"
00014
00015 #define NEXTVAL(x) ( (lquery*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
00016
00017 PG_FUNCTION_INFO_V1(ltree_gist_in);
00018 Datum ltree_gist_in(PG_FUNCTION_ARGS);
00019
00020 PG_FUNCTION_INFO_V1(ltree_gist_out);
00021 Datum ltree_gist_out(PG_FUNCTION_ARGS);
00022
00023 Datum
00024 ltree_gist_in(PG_FUNCTION_ARGS)
00025 {
00026 ereport(ERROR,
00027 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00028 errmsg("ltree_gist_in() not implemented")));
00029 PG_RETURN_DATUM(0);
00030 }
00031
00032 Datum
00033 ltree_gist_out(PG_FUNCTION_ARGS)
00034 {
00035 ereport(ERROR,
00036 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00037 errmsg("ltree_gist_out() not implemented")));
00038 PG_RETURN_DATUM(0);
00039 }
00040
00041 PG_FUNCTION_INFO_V1(ltree_compress);
00042 Datum ltree_compress(PG_FUNCTION_ARGS);
00043
00044 PG_FUNCTION_INFO_V1(ltree_decompress);
00045 Datum ltree_decompress(PG_FUNCTION_ARGS);
00046
00047 PG_FUNCTION_INFO_V1(ltree_same);
00048 Datum ltree_same(PG_FUNCTION_ARGS);
00049
00050 PG_FUNCTION_INFO_V1(ltree_union);
00051 Datum ltree_union(PG_FUNCTION_ARGS);
00052
00053 PG_FUNCTION_INFO_V1(ltree_penalty);
00054 Datum ltree_penalty(PG_FUNCTION_ARGS);
00055
00056 PG_FUNCTION_INFO_V1(ltree_picksplit);
00057 Datum ltree_picksplit(PG_FUNCTION_ARGS);
00058
00059 PG_FUNCTION_INFO_V1(ltree_consistent);
00060 Datum ltree_consistent(PG_FUNCTION_ARGS);
00061
00062 #define ISEQ(a,b) ( (a)->numlevel == (b)->numlevel && ltree_compare(a,b)==0 )
00063 #define GETENTRY(vec,pos) ((ltree_gist *) DatumGetPointer((vec)->vector[(pos)].key))
00064
00065 Datum
00066 ltree_compress(PG_FUNCTION_ARGS)
00067 {
00068 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00069 GISTENTRY *retval = entry;
00070
00071 if (entry->leafkey)
00072 {
00073 ltree_gist *key;
00074 ltree *val = (ltree *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));
00075 int4 len = LTG_HDRSIZE + VARSIZE(val);
00076
00077 key = (ltree_gist *) palloc(len);
00078 SET_VARSIZE(key, len);
00079 key->flag = LTG_ONENODE;
00080 memcpy((void *) LTG_NODE(key), (void *) val, VARSIZE(val));
00081
00082 retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
00083 gistentryinit(*retval, PointerGetDatum(key),
00084 entry->rel, entry->page,
00085 entry->offset, FALSE);
00086 }
00087 PG_RETURN_POINTER(retval);
00088 }
00089
00090 Datum
00091 ltree_decompress(PG_FUNCTION_ARGS)
00092 {
00093 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00094 ltree_gist *key = (ltree_gist *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));
00095
00096 if (PointerGetDatum(key) != entry->key)
00097 {
00098 GISTENTRY *retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
00099
00100 gistentryinit(*retval, PointerGetDatum(key),
00101 entry->rel, entry->page,
00102 entry->offset, FALSE);
00103 PG_RETURN_POINTER(retval);
00104 }
00105 PG_RETURN_POINTER(entry);
00106 }
00107
00108 Datum
00109 ltree_same(PG_FUNCTION_ARGS)
00110 {
00111 ltree_gist *a = (ltree_gist *) PG_GETARG_POINTER(0);
00112 ltree_gist *b = (ltree_gist *) PG_GETARG_POINTER(1);
00113 bool *result = (bool *) PG_GETARG_POINTER(2);
00114
00115 *result = false;
00116 if (LTG_ISONENODE(a) != LTG_ISONENODE(b))
00117 PG_RETURN_POINTER(result);
00118
00119 if (LTG_ISONENODE(a))
00120 *result = (ISEQ(LTG_NODE(a), LTG_NODE(b))) ? true : false;
00121 else
00122 {
00123 int4 i;
00124 BITVECP sa = LTG_SIGN(a),
00125 sb = LTG_SIGN(b);
00126
00127 if (LTG_ISALLTRUE(a) != LTG_ISALLTRUE(b))
00128 PG_RETURN_POINTER(result);
00129
00130 if (!ISEQ(LTG_LNODE(a), LTG_LNODE(b)))
00131 PG_RETURN_POINTER(result);
00132 if (!ISEQ(LTG_RNODE(a), LTG_RNODE(b)))
00133 PG_RETURN_POINTER(result);
00134
00135 *result = true;
00136 if (!LTG_ISALLTRUE(a))
00137 {
00138 LOOPBYTE
00139 {
00140 if (sa[i] != sb[i])
00141 {
00142 *result = false;
00143 break;
00144 }
00145 }
00146 }
00147 }
00148
00149 PG_RETURN_POINTER(result);
00150 }
00151
00152 static void
00153 hashing(BITVECP sign, ltree *t)
00154 {
00155 int tlen = t->numlevel;
00156 ltree_level *cur = LTREE_FIRST(t);
00157 int hash;
00158
00159 while (tlen > 0)
00160 {
00161 hash = ltree_crc32_sz(cur->name, cur->len);
00162 HASH(sign, hash);
00163 cur = LEVEL_NEXT(cur);
00164 tlen--;
00165 }
00166 }
00167
00168 Datum
00169 ltree_union(PG_FUNCTION_ARGS)
00170 {
00171 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
00172 int *size = (int *) PG_GETARG_POINTER(1);
00173 BITVEC base;
00174 int4 i,
00175 j;
00176 ltree_gist *result,
00177 *cur;
00178 ltree *left = NULL,
00179 *right = NULL,
00180 *curtree;
00181 bool isalltrue = false;
00182 bool isleqr;
00183
00184 MemSet((void *) base, 0, sizeof(BITVEC));
00185 for (j = 0; j < entryvec->n; j++)
00186 {
00187 cur = GETENTRY(entryvec, j);
00188 if (LTG_ISONENODE(cur))
00189 {
00190 curtree = LTG_NODE(cur);
00191 hashing(base, curtree);
00192 if (!left || ltree_compare(left, curtree) > 0)
00193 left = curtree;
00194 if (!right || ltree_compare(right, curtree) < 0)
00195 right = curtree;
00196 }
00197 else
00198 {
00199 if (isalltrue || LTG_ISALLTRUE(cur))
00200 isalltrue = true;
00201 else
00202 {
00203 BITVECP sc = LTG_SIGN(cur);
00204
00205 LOOPBYTE
00206 ((unsigned char *) base)[i] |= sc[i];
00207 }
00208
00209 curtree = LTG_LNODE(cur);
00210 if (!left || ltree_compare(left, curtree) > 0)
00211 left = curtree;
00212 curtree = LTG_RNODE(cur);
00213 if (!right || ltree_compare(right, curtree) < 0)
00214 right = curtree;
00215 }
00216 }
00217
00218 if (isalltrue == false)
00219 {
00220 isalltrue = true;
00221 LOOPBYTE
00222 {
00223 if (((unsigned char *) base)[i] != 0xff)
00224 {
00225 isalltrue = false;
00226 break;
00227 }
00228 }
00229 }
00230
00231 isleqr = (left == right || ISEQ(left, right)) ? true : false;
00232 *size = LTG_HDRSIZE + ((isalltrue) ? 0 : SIGLEN) + VARSIZE(left) + ((isleqr) ? 0 : VARSIZE(right));
00233
00234 result = (ltree_gist *) palloc(*size);
00235 SET_VARSIZE(result, *size);
00236 result->flag = 0;
00237
00238 if (isalltrue)
00239 result->flag |= LTG_ALLTRUE;
00240 else
00241 memcpy((void *) LTG_SIGN(result), base, SIGLEN);
00242
00243 memcpy((void *) LTG_LNODE(result), (void *) left, VARSIZE(left));
00244 if (isleqr)
00245 result->flag |= LTG_NORIGHT;
00246 else
00247 memcpy((void *) LTG_RNODE(result), (void *) right, VARSIZE(right));
00248
00249 PG_RETURN_POINTER(result);
00250 }
00251
00252 Datum
00253 ltree_penalty(PG_FUNCTION_ARGS)
00254 {
00255 ltree_gist *origval = (ltree_gist *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
00256 ltree_gist *newval = (ltree_gist *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
00257 float *penalty = (float *) PG_GETARG_POINTER(2);
00258 int4 cmpr,
00259 cmpl;
00260
00261 cmpl = ltree_compare(LTG_GETLNODE(origval), LTG_GETLNODE(newval));
00262 cmpr = ltree_compare(LTG_GETRNODE(newval), LTG_GETRNODE(origval));
00263
00264 *penalty = Max(cmpl, 0) + Max(cmpr, 0);
00265
00266 PG_RETURN_POINTER(penalty);
00267 }
00268
00269
00270 typedef struct rix
00271 {
00272 int index;
00273 ltree *r;
00274 } RIX;
00275
00276 static int
00277 treekey_cmp(const void *a, const void *b)
00278 {
00279 return ltree_compare(
00280 ((RIX *) a)->r,
00281 ((RIX *) b)->r
00282 );
00283 }
00284
00285
00286 Datum
00287 ltree_picksplit(PG_FUNCTION_ARGS)
00288 {
00289 GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
00290 GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
00291 OffsetNumber j;
00292 int4 i;
00293 RIX *array;
00294 OffsetNumber maxoff;
00295 int nbytes;
00296 int size;
00297 ltree *lu_l,
00298 *lu_r,
00299 *ru_l,
00300 *ru_r;
00301 ltree_gist *lu,
00302 *ru;
00303 BITVEC ls,
00304 rs;
00305 bool lisat = false,
00306 risat = false,
00307 isleqr;
00308
00309 memset((void *) ls, 0, sizeof(BITVEC));
00310 memset((void *) rs, 0, sizeof(BITVEC));
00311 maxoff = entryvec->n - 1;
00312 nbytes = (maxoff + 2) * sizeof(OffsetNumber);
00313 v->spl_left = (OffsetNumber *) palloc(nbytes);
00314 v->spl_right = (OffsetNumber *) palloc(nbytes);
00315 v->spl_nleft = 0;
00316 v->spl_nright = 0;
00317 array = (RIX *) palloc(sizeof(RIX) * (maxoff + 1));
00318
00319
00320 for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
00321 {
00322 array[j].index = j;
00323 lu = GETENTRY(entryvec, j);
00324 array[j].r = LTG_GETLNODE(lu);
00325 }
00326
00327 qsort((void *) &array[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1,
00328 sizeof(RIX), treekey_cmp);
00329
00330 lu_l = lu_r = ru_l = ru_r = NULL;
00331 for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
00332 {
00333 lu = GETENTRY(entryvec, array[j].index);
00334 if (j <= (maxoff - FirstOffsetNumber + 1) / 2)
00335 {
00336 v->spl_left[v->spl_nleft] = array[j].index;
00337 v->spl_nleft++;
00338 if (lu_r == NULL || ltree_compare(LTG_GETRNODE(lu), lu_r) > 0)
00339 lu_r = LTG_GETRNODE(lu);
00340 if (LTG_ISONENODE(lu))
00341 hashing(ls, LTG_NODE(lu));
00342 else
00343 {
00344 if (lisat || LTG_ISALLTRUE(lu))
00345 lisat = true;
00346 else
00347 {
00348 BITVECP sc = LTG_SIGN(lu);
00349
00350 LOOPBYTE
00351 ((unsigned char *) ls)[i] |= sc[i];
00352 }
00353 }
00354 }
00355 else
00356 {
00357 v->spl_right[v->spl_nright] = array[j].index;
00358 v->spl_nright++;
00359 if (ru_r == NULL || ltree_compare(LTG_GETRNODE(lu), ru_r) > 0)
00360 ru_r = LTG_GETRNODE(lu);
00361 if (LTG_ISONENODE(lu))
00362 hashing(rs, LTG_NODE(lu));
00363 else
00364 {
00365 if (risat || LTG_ISALLTRUE(lu))
00366 risat = true;
00367 else
00368 {
00369 BITVECP sc = LTG_SIGN(lu);
00370
00371 LOOPBYTE
00372 ((unsigned char *) rs)[i] |= sc[i];
00373 }
00374 }
00375 }
00376 }
00377
00378 if (lisat == false)
00379 {
00380 lisat = true;
00381 LOOPBYTE
00382 {
00383 if (((unsigned char *) ls)[i] != 0xff)
00384 {
00385 lisat = false;
00386 break;
00387 }
00388 }
00389 }
00390
00391 if (risat == false)
00392 {
00393 risat = true;
00394 LOOPBYTE
00395 {
00396 if (((unsigned char *) rs)[i] != 0xff)
00397 {
00398 risat = false;
00399 break;
00400 }
00401 }
00402 }
00403
00404 lu_l = LTG_GETLNODE(GETENTRY(entryvec, array[FirstOffsetNumber].index));
00405 isleqr = (lu_l == lu_r || ISEQ(lu_l, lu_r)) ? true : false;
00406 size = LTG_HDRSIZE + ((lisat) ? 0 : SIGLEN) + VARSIZE(lu_l) + ((isleqr) ? 0 : VARSIZE(lu_r));
00407 lu = (ltree_gist *) palloc(size);
00408 SET_VARSIZE(lu, size);
00409 lu->flag = 0;
00410 if (lisat)
00411 lu->flag |= LTG_ALLTRUE;
00412 else
00413 memcpy((void *) LTG_SIGN(lu), ls, SIGLEN);
00414 memcpy((void *) LTG_LNODE(lu), (void *) lu_l, VARSIZE(lu_l));
00415 if (isleqr)
00416 lu->flag |= LTG_NORIGHT;
00417 else
00418 memcpy((void *) LTG_RNODE(lu), (void *) lu_r, VARSIZE(lu_r));
00419
00420
00421 ru_l = LTG_GETLNODE(GETENTRY(entryvec, array[1 + ((maxoff - FirstOffsetNumber + 1) / 2)].index));
00422 isleqr = (ru_l == ru_r || ISEQ(ru_l, ru_r)) ? true : false;
00423 size = LTG_HDRSIZE + ((risat) ? 0 : SIGLEN) + VARSIZE(ru_l) + ((isleqr) ? 0 : VARSIZE(ru_r));
00424 ru = (ltree_gist *) palloc(size);
00425 SET_VARSIZE(ru, size);
00426 ru->flag = 0;
00427 if (risat)
00428 ru->flag |= LTG_ALLTRUE;
00429 else
00430 memcpy((void *) LTG_SIGN(ru), rs, SIGLEN);
00431 memcpy((void *) LTG_LNODE(ru), (void *) ru_l, VARSIZE(ru_l));
00432 if (isleqr)
00433 ru->flag |= LTG_NORIGHT;
00434 else
00435 memcpy((void *) LTG_RNODE(ru), (void *) ru_r, VARSIZE(ru_r));
00436
00437 v->spl_ldatum = PointerGetDatum(lu);
00438 v->spl_rdatum = PointerGetDatum(ru);
00439
00440 PG_RETURN_POINTER(v);
00441 }
00442
00443 static bool
00444 gist_isparent(ltree_gist *key, ltree *query)
00445 {
00446 int4 numlevel = query->numlevel;
00447 int i;
00448
00449 for (i = query->numlevel; i >= 0; i--)
00450 {
00451 query->numlevel = i;
00452 if (ltree_compare(query, LTG_GETLNODE(key)) >= 0 && ltree_compare(query, LTG_GETRNODE(key)) <= 0)
00453 {
00454 query->numlevel = numlevel;
00455 return true;
00456 }
00457 }
00458
00459 query->numlevel = numlevel;
00460 return false;
00461 }
00462
00463 static ltree *
00464 copy_ltree(ltree *src)
00465 {
00466 ltree *dst = (ltree *) palloc(VARSIZE(src));
00467
00468 memcpy(dst, src, VARSIZE(src));
00469 return dst;
00470 }
00471
00472 static bool
00473 gist_ischild(ltree_gist *key, ltree *query)
00474 {
00475 ltree *left = copy_ltree(LTG_GETLNODE(key));
00476 ltree *right = copy_ltree(LTG_GETRNODE(key));
00477 bool res = true;
00478
00479 if (left->numlevel > query->numlevel)
00480 left->numlevel = query->numlevel;
00481
00482 if (ltree_compare(query, left) < 0)
00483 res = false;
00484
00485 if (right->numlevel > query->numlevel)
00486 right->numlevel = query->numlevel;
00487
00488 if (res && ltree_compare(query, right) > 0)
00489 res = false;
00490
00491 pfree(left);
00492 pfree(right);
00493
00494 return res;
00495 }
00496
00497 static bool
00498 gist_qe(ltree_gist *key, lquery *query)
00499 {
00500 lquery_level *curq = LQUERY_FIRST(query);
00501 BITVECP sign = LTG_SIGN(key);
00502 int qlen = query->numlevel;
00503
00504 if (LTG_ISALLTRUE(key))
00505 return true;
00506
00507 while (qlen > 0)
00508 {
00509 if (curq->numvar && LQL_CANLOOKSIGN(curq))
00510 {
00511 bool isexist = false;
00512 int vlen = curq->numvar;
00513 lquery_variant *curv = LQL_FIRST(curq);
00514
00515 while (vlen > 0)
00516 {
00517 if (GETBIT(sign, HASHVAL(curv->val)))
00518 {
00519 isexist = true;
00520 break;
00521 }
00522 curv = LVAR_NEXT(curv);
00523 vlen--;
00524 }
00525 if (!isexist)
00526 return false;
00527 }
00528
00529 curq = LQL_NEXT(curq);
00530 qlen--;
00531 }
00532
00533 return true;
00534 }
00535
00536 static int
00537 gist_tqcmp(ltree *t, lquery *q)
00538 {
00539 ltree_level *al = LTREE_FIRST(t);
00540 lquery_level *ql = LQUERY_FIRST(q);
00541 lquery_variant *bl;
00542 int an = t->numlevel;
00543 int bn = q->firstgood;
00544 int res = 0;
00545
00546 while (an > 0 && bn > 0)
00547 {
00548 bl = LQL_FIRST(ql);
00549 if ((res = memcmp(al->name, bl->name, Min(al->len, bl->len))) == 0)
00550 {
00551 if (al->len != bl->len)
00552 return al->len - bl->len;
00553 }
00554 else
00555 return res;
00556 an--;
00557 bn--;
00558 al = LEVEL_NEXT(al);
00559 ql = LQL_NEXT(ql);
00560 }
00561
00562 return Min(t->numlevel, q->firstgood) - q->firstgood;
00563 }
00564
00565 static bool
00566 gist_between(ltree_gist *key, lquery *query)
00567 {
00568 if (query->firstgood == 0)
00569 return true;
00570
00571 if (gist_tqcmp(LTG_GETLNODE(key), query) > 0)
00572 return false;
00573
00574 if (gist_tqcmp(LTG_GETRNODE(key), query) < 0)
00575 return false;
00576
00577 return true;
00578 }
00579
00580 static bool
00581 checkcondition_bit(void *checkval, ITEM *val)
00582 {
00583 return (FLG_CANLOOKSIGN(val->flag)) ? GETBIT(checkval, HASHVAL(val->val)) : true;
00584 }
00585
00586 static bool
00587 gist_qtxt(ltree_gist *key, ltxtquery *query)
00588 {
00589 if (LTG_ISALLTRUE(key))
00590 return true;
00591
00592 return ltree_execute(
00593 GETQUERY(query),
00594 (void *) LTG_SIGN(key), false,
00595 checkcondition_bit
00596 );
00597 }
00598
00599 static bool
00600 arrq_cons(ltree_gist *key, ArrayType *_query)
00601 {
00602 lquery *query = (lquery *) ARR_DATA_PTR(_query);
00603 int num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
00604
00605 if (ARR_NDIM(_query) > 1)
00606 ereport(ERROR,
00607 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
00608 errmsg("array must be one-dimensional")));
00609 if (array_contains_nulls(_query))
00610 ereport(ERROR,
00611 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
00612 errmsg("array must not contain nulls")));
00613
00614 while (num > 0)
00615 {
00616 if (gist_qe(key, query) && gist_between(key, query))
00617 return true;
00618 num--;
00619 query = NEXTVAL(query);
00620 }
00621 return false;
00622 }
00623
00624 Datum
00625 ltree_consistent(PG_FUNCTION_ARGS)
00626 {
00627 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
00628 StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
00629
00630
00631 bool *recheck = (bool *) PG_GETARG_POINTER(4);
00632 ltree_gist *key = (ltree_gist *) DatumGetPointer(entry->key);
00633 void *query = NULL;
00634 bool res = false;
00635
00636
00637 *recheck = false;
00638
00639 switch (strategy)
00640 {
00641 case BTLessStrategyNumber:
00642 query = PG_GETARG_LTREE(1);
00643 res = (GIST_LEAF(entry)) ?
00644 (ltree_compare((ltree *) query, LTG_NODE(key)) > 0)
00645 :
00646 (ltree_compare((ltree *) query, LTG_GETLNODE(key)) >= 0);
00647 break;
00648 case BTLessEqualStrategyNumber:
00649 query = PG_GETARG_LTREE(1);
00650 res = (ltree_compare((ltree *) query, LTG_GETLNODE(key)) >= 0);
00651 break;
00652 case BTEqualStrategyNumber:
00653 query = PG_GETARG_LTREE(1);
00654 if (GIST_LEAF(entry))
00655 res = (ltree_compare((ltree *) query, LTG_NODE(key)) == 0);
00656 else
00657 res = (
00658 ltree_compare((ltree *) query, LTG_GETLNODE(key)) >= 0
00659 &&
00660 ltree_compare((ltree *) query, LTG_GETRNODE(key)) <= 0
00661 );
00662 break;
00663 case BTGreaterEqualStrategyNumber:
00664 query = PG_GETARG_LTREE(1);
00665 res = (ltree_compare((ltree *) query, LTG_GETRNODE(key)) <= 0);
00666 break;
00667 case BTGreaterStrategyNumber:
00668 query = PG_GETARG_LTREE(1);
00669 res = (GIST_LEAF(entry)) ?
00670 (ltree_compare((ltree *) query, LTG_GETRNODE(key)) < 0)
00671 :
00672 (ltree_compare((ltree *) query, LTG_GETRNODE(key)) <= 0);
00673 break;
00674 case 10:
00675 query = PG_GETARG_LTREE_COPY(1);
00676 res = (GIST_LEAF(entry)) ?
00677 inner_isparent((ltree *) query, LTG_NODE(key))
00678 :
00679 gist_isparent(key, (ltree *) query);
00680 break;
00681 case 11:
00682 query = PG_GETARG_LTREE(1);
00683 res = (GIST_LEAF(entry)) ?
00684 inner_isparent(LTG_NODE(key), (ltree *) query)
00685 :
00686 gist_ischild(key, (ltree *) query);
00687 break;
00688 case 12:
00689 case 13:
00690 query = PG_GETARG_LQUERY(1);
00691 if (GIST_LEAF(entry))
00692 res = DatumGetBool(DirectFunctionCall2(ltq_regex,
00693 PointerGetDatum(LTG_NODE(key)),
00694 PointerGetDatum((lquery *) query)
00695 ));
00696 else
00697 res = (gist_qe(key, (lquery *) query) && gist_between(key, (lquery *) query));
00698 break;
00699 case 14:
00700 case 15:
00701 query = PG_GETARG_LQUERY(1);
00702 if (GIST_LEAF(entry))
00703 res = DatumGetBool(DirectFunctionCall2(ltxtq_exec,
00704 PointerGetDatum(LTG_NODE(key)),
00705 PointerGetDatum((lquery *) query)
00706 ));
00707 else
00708 res = gist_qtxt(key, (ltxtquery *) query);
00709 break;
00710 case 16:
00711 case 17:
00712 query = DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1)));
00713 if (GIST_LEAF(entry))
00714 res = DatumGetBool(DirectFunctionCall2(lt_q_regex,
00715 PointerGetDatum(LTG_NODE(key)),
00716 PointerGetDatum((ArrayType *) query)
00717 ));
00718 else
00719 res = arrq_cons(key, (ArrayType *) query);
00720 break;
00721 default:
00722
00723 elog(ERROR, "unrecognized StrategyNumber: %d", strategy);
00724 }
00725
00726 PG_FREE_IF_COPY(query, 1);
00727 PG_RETURN_BOOL(res);
00728 }