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