PostgreSQL Source Code git master
ltree_gist.c
Go to the documentation of this file.
1/*
2 * GiST support for ltree
3 * Teodor Sigaev <teodor@stack.net>
4 * contrib/ltree/ltree_gist.c
5 */
6#include "postgres.h"
7
8#include "access/gist.h"
9#include "access/reloptions.h"
10#include "access/stratnum.h"
11#include "crc32.h"
12#include "ltree.h"
13#include "utils/array.h"
14
15#define NEXTVAL(x) ( (lquery*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
16#define ISEQ(a,b) ( (a)->numlevel == (b)->numlevel && ltree_compare(a,b)==0 )
17
20
23{
25 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
26 errmsg("cannot accept a value of type %s", "ltree_gist")));
27
28 PG_RETURN_VOID(); /* keep compiler quiet */
29}
30
33{
35 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
36 errmsg("cannot display a value of type %s", "ltree_gist")));
37
38 PG_RETURN_VOID(); /* keep compiler quiet */
39}
40
42ltree_gist_alloc(bool isalltrue, BITVECP sign, int siglen,
43 ltree *left, ltree *right)
44{
45 int32 size = LTG_HDRSIZE + (isalltrue ? 0 : siglen) +
46 (left ? VARSIZE(left) + (right ? VARSIZE(right) : 0) : 0);
47 ltree_gist *result = palloc(size);
48
49 SET_VARSIZE(result, size);
50
51 if (siglen)
52 {
53 result->flag = 0;
54
55 if (isalltrue)
56 result->flag |= LTG_ALLTRUE;
57 else if (sign)
58 memcpy(LTG_SIGN(result), sign, siglen);
59 else
60 memset(LTG_SIGN(result), 0, siglen);
61
62 if (left)
63 {
64 memcpy(LTG_LNODE(result, siglen), left, VARSIZE(left));
65
66 if (!right || left == right || ISEQ(left, right))
67 result->flag |= LTG_NORIGHT;
68 else
69 memcpy(LTG_RNODE(result, siglen), right, VARSIZE(right));
70 }
71 }
72 else
73 {
74 Assert(left);
75 result->flag = LTG_ONENODE;
76 memcpy(LTG_NODE(result), left, VARSIZE(left));
77 }
78
79 return result;
80}
81
90
91#define GETENTRY(vec,pos) ((ltree_gist *) DatumGetPointer((vec)->vector[(pos)].key))
92
95{
97 GISTENTRY *retval = entry;
98
99 if (entry->leafkey)
100 { /* ltree */
101 ltree *val = DatumGetLtreeP(entry->key);
102 ltree_gist *key = ltree_gist_alloc(false, NULL, 0, val, 0);
103
104 retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
106 entry->rel, entry->page,
107 entry->offset, false);
108 }
109 PG_RETURN_POINTER(retval);
110}
111
112Datum
114{
115 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
117
118 if (PointerGetDatum(key) != entry->key)
119 {
120 GISTENTRY *retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
121
123 entry->rel, entry->page,
124 entry->offset, false);
125 PG_RETURN_POINTER(retval);
126 }
127 PG_RETURN_POINTER(entry);
128}
129
130Datum
132{
135 bool *result = (bool *) PG_GETARG_POINTER(2);
136 int siglen = LTREE_GET_SIGLEN();
137
138 *result = false;
140 PG_RETURN_POINTER(result);
141
142 if (LTG_ISONENODE(a))
143 *result = ISEQ(LTG_NODE(a), LTG_NODE(b));
144 else
145 {
146 int32 i;
147 BITVECP sa = LTG_SIGN(a),
148 sb = LTG_SIGN(b);
149
151 PG_RETURN_POINTER(result);
152
153 if (!ISEQ(LTG_LNODE(a, siglen), LTG_LNODE(b, siglen)))
154 PG_RETURN_POINTER(result);
155 if (!ISEQ(LTG_RNODE(a, siglen), LTG_RNODE(b, siglen)))
156 PG_RETURN_POINTER(result);
157
158 *result = true;
159 if (!LTG_ISALLTRUE(a))
160 {
161 LOOPBYTE(siglen)
162 {
163 if (sa[i] != sb[i])
164 {
165 *result = false;
166 break;
167 }
168 }
169 }
170 }
171
172 PG_RETURN_POINTER(result);
173}
174
175static void
176hashing(BITVECP sign, ltree *t, int siglen)
177{
178 int tlen = t->numlevel;
180 int hash;
181
182 while (tlen > 0)
183 {
184 hash = ltree_crc32_sz(cur->name, cur->len);
185 HASH(sign, hash, siglen);
186 cur = LEVEL_NEXT(cur);
187 tlen--;
188 }
189}
190
191Datum
193{
195 int *size = (int *) PG_GETARG_POINTER(1);
196 int siglen = LTREE_GET_SIGLEN();
197 BITVECP base = palloc0(siglen);
198 int32 i,
199 j;
200 ltree_gist *result,
201 *cur;
202 ltree *left = NULL,
203 *right = NULL,
204 *curtree;
205 bool isalltrue = false;
206
207 for (j = 0; j < entryvec->n; j++)
208 {
209 cur = GETENTRY(entryvec, j);
210 if (LTG_ISONENODE(cur))
211 {
212 curtree = LTG_NODE(cur);
213 hashing(base, curtree, siglen);
214 if (!left || ltree_compare(left, curtree) > 0)
215 left = curtree;
216 if (!right || ltree_compare(right, curtree) < 0)
217 right = curtree;
218 }
219 else
220 {
221 if (isalltrue || LTG_ISALLTRUE(cur))
222 isalltrue = true;
223 else
224 {
225 BITVECP sc = LTG_SIGN(cur);
226
227 LOOPBYTE(siglen)
228 ((unsigned char *) base)[i] |= sc[i];
229 }
230
231 curtree = LTG_LNODE(cur, siglen);
232 if (!left || ltree_compare(left, curtree) > 0)
233 left = curtree;
234 curtree = LTG_RNODE(cur, siglen);
235 if (!right || ltree_compare(right, curtree) < 0)
236 right = curtree;
237 }
238 }
239
240 if (isalltrue == false)
241 {
242 isalltrue = true;
243 LOOPBYTE(siglen)
244 {
245 if (((unsigned char *) base)[i] != 0xff)
246 {
247 isalltrue = false;
248 break;
249 }
250 }
251 }
252
253 result = ltree_gist_alloc(isalltrue, base, siglen, left, right);
254
255 *size = VARSIZE(result);
256
257 PG_RETURN_POINTER(result);
258}
259
260Datum
262{
265 float *penalty = (float *) PG_GETARG_POINTER(2);
266 int siglen = LTREE_GET_SIGLEN();
267 int32 cmpr,
268 cmpl;
269
270 cmpl = ltree_compare(LTG_GETLNODE(origval, siglen), LTG_GETLNODE(newval, siglen));
271 cmpr = ltree_compare(LTG_GETRNODE(newval, siglen), LTG_GETRNODE(origval, siglen));
272
273 *penalty = Max(cmpl, 0) + Max(cmpr, 0);
274
275 PG_RETURN_POINTER(penalty);
276}
277
278/* used for sorting */
279typedef struct rix
280{
281 int index;
284
285static int
286treekey_cmp(const void *a, const void *b)
287{
288 return ltree_compare(((const RIX *) a)->r,
289 ((const RIX *) b)->r);
290}
291
292
293Datum
295{
298 int siglen = LTREE_GET_SIGLEN();
300 int32 i;
301 RIX *array;
302 OffsetNumber maxoff;
303 int nbytes;
304 ltree *lu_l,
305 *lu_r,
306 *ru_l,
307 *ru_r;
308 ltree_gist *lu,
309 *ru;
310 BITVECP ls = palloc0(siglen),
311 rs = palloc0(siglen);
312 bool lisat = false,
313 risat = false;
314
315 maxoff = entryvec->n - 1;
316 nbytes = (maxoff + 2) * sizeof(OffsetNumber);
317 v->spl_left = (OffsetNumber *) palloc(nbytes);
318 v->spl_right = (OffsetNumber *) palloc(nbytes);
319 v->spl_nleft = 0;
320 v->spl_nright = 0;
321 array = (RIX *) palloc(sizeof(RIX) * (maxoff + 1));
322
323 /* copy the data into RIXes, and sort the RIXes */
324 for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
325 {
326 array[j].index = j;
327 lu = GETENTRY(entryvec, j); /* use as tmp val */
328 array[j].r = LTG_GETLNODE(lu, siglen);
329 }
330
331 qsort(&array[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1,
332 sizeof(RIX), treekey_cmp);
333
334 lu_l = lu_r = ru_l = ru_r = NULL;
335 for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
336 {
337 lu = GETENTRY(entryvec, array[j].index); /* use as tmp val */
338 if (j <= (maxoff - FirstOffsetNumber + 1) / 2)
339 {
340 v->spl_left[v->spl_nleft] = array[j].index;
341 v->spl_nleft++;
342 if (lu_r == NULL || ltree_compare(LTG_GETRNODE(lu, siglen), lu_r) > 0)
343 lu_r = LTG_GETRNODE(lu, siglen);
344 if (LTG_ISONENODE(lu))
345 hashing(ls, LTG_NODE(lu), siglen);
346 else
347 {
348 if (lisat || LTG_ISALLTRUE(lu))
349 lisat = true;
350 else
351 {
352 BITVECP sc = LTG_SIGN(lu);
353
354 LOOPBYTE(siglen)
355 ((unsigned char *) ls)[i] |= sc[i];
356 }
357 }
358 }
359 else
360 {
361 v->spl_right[v->spl_nright] = array[j].index;
362 v->spl_nright++;
363 if (ru_r == NULL || ltree_compare(LTG_GETRNODE(lu, siglen), ru_r) > 0)
364 ru_r = LTG_GETRNODE(lu, siglen);
365 if (LTG_ISONENODE(lu))
366 hashing(rs, LTG_NODE(lu), siglen);
367 else
368 {
369 if (risat || LTG_ISALLTRUE(lu))
370 risat = true;
371 else
372 {
373 BITVECP sc = LTG_SIGN(lu);
374
375 LOOPBYTE(siglen)
376 ((unsigned char *) rs)[i] |= sc[i];
377 }
378 }
379 }
380 }
381
382 if (lisat == false)
383 {
384 lisat = true;
385 LOOPBYTE(siglen)
386 {
387 if (((unsigned char *) ls)[i] != 0xff)
388 {
389 lisat = false;
390 break;
391 }
392 }
393 }
394
395 if (risat == false)
396 {
397 risat = true;
398 LOOPBYTE(siglen)
399 {
400 if (((unsigned char *) rs)[i] != 0xff)
401 {
402 risat = false;
403 break;
404 }
405 }
406 }
407
408 lu_l = LTG_GETLNODE(GETENTRY(entryvec, array[FirstOffsetNumber].index), siglen);
409 lu = ltree_gist_alloc(lisat, ls, siglen, lu_l, lu_r);
410
411 ru_l = LTG_GETLNODE(GETENTRY(entryvec, array[1 + ((maxoff - FirstOffsetNumber + 1) / 2)].index), siglen);
412 ru = ltree_gist_alloc(risat, rs, siglen, ru_l, ru_r);
413
414 pfree(ls);
415 pfree(rs);
416
419
421}
422
423static bool
424gist_isparent(ltree_gist *key, ltree *query, int siglen)
425{
426 int32 numlevel = query->numlevel;
427 int i;
428
429 for (i = query->numlevel; i >= 0; i--)
430 {
431 query->numlevel = i;
432 if (ltree_compare(query, LTG_GETLNODE(key, siglen)) >= 0 &&
433 ltree_compare(query, LTG_GETRNODE(key, siglen)) <= 0)
434 {
435 query->numlevel = numlevel;
436 return true;
437 }
438 }
439
440 query->numlevel = numlevel;
441 return false;
442}
443
444static ltree *
446{
447 ltree *dst = (ltree *) palloc0(VARSIZE(src));
448
449 memcpy(dst, src, VARSIZE(src));
450 return dst;
451}
452
453static bool
454gist_ischild(ltree_gist *key, ltree *query, int siglen)
455{
456 ltree *left = copy_ltree(LTG_GETLNODE(key, siglen));
457 ltree *right = copy_ltree(LTG_GETRNODE(key, siglen));
458 bool res = true;
459
460 if (left->numlevel > query->numlevel)
461 left->numlevel = query->numlevel;
462
463 if (ltree_compare(query, left) < 0)
464 res = false;
465
466 if (right->numlevel > query->numlevel)
467 right->numlevel = query->numlevel;
468
469 if (res && ltree_compare(query, right) > 0)
470 res = false;
471
472 pfree(left);
473 pfree(right);
474
475 return res;
476}
477
478static bool
479gist_qe(ltree_gist *key, lquery *query, int siglen)
480{
481 lquery_level *curq = LQUERY_FIRST(query);
483 int qlen = query->numlevel;
484
485 if (LTG_ISALLTRUE(key))
486 return true;
487
488 while (qlen > 0)
489 {
490 if (curq->numvar && LQL_CANLOOKSIGN(curq))
491 {
492 bool isexist = false;
493 int vlen = curq->numvar;
494 lquery_variant *curv = LQL_FIRST(curq);
495
496 while (vlen > 0)
497 {
498 if (GETBIT(sign, HASHVAL(curv->val, siglen)))
499 {
500 isexist = true;
501 break;
502 }
503 curv = LVAR_NEXT(curv);
504 vlen--;
505 }
506 if (!isexist)
507 return false;
508 }
509
510 curq = LQL_NEXT(curq);
511 qlen--;
512 }
513
514 return true;
515}
516
517static int
519{
520 ltree_level *al = LTREE_FIRST(t);
521 lquery_level *ql = LQUERY_FIRST(q);
522 lquery_variant *bl;
523 int an = t->numlevel;
524 int bn = q->firstgood;
525 int res = 0;
526
527 while (an > 0 && bn > 0)
528 {
529 bl = LQL_FIRST(ql);
530 if ((res = memcmp(al->name, bl->name, Min(al->len, bl->len))) == 0)
531 {
532 if (al->len != bl->len)
533 return al->len - bl->len;
534 }
535 else
536 return res;
537 an--;
538 bn--;
539 al = LEVEL_NEXT(al);
540 ql = LQL_NEXT(ql);
541 }
542
543 return Min(t->numlevel, q->firstgood) - q->firstgood;
544}
545
546static bool
547gist_between(ltree_gist *key, lquery *query, int siglen)
548{
549 if (query->firstgood == 0)
550 return true;
551
552 if (gist_tqcmp(LTG_GETLNODE(key, siglen), query) > 0)
553 return false;
554
555 if (gist_tqcmp(LTG_GETRNODE(key, siglen), query) < 0)
556 return false;
557
558 return true;
559}
560
561typedef struct LtreeSignature
562{
564 int siglen;
566
567static bool
569{
570 LtreeSignature *sig = cxt;
571
572 return (FLG_CANLOOKSIGN(val->flag)) ? GETBIT(sig->sign, HASHVAL(val->val, sig->siglen)) : true;
573}
574
575static bool
576gist_qtxt(ltree_gist *key, ltxtquery *query, int siglen)
577{
579
580 if (LTG_ISALLTRUE(key))
581 return true;
582
583 sig.sign = LTG_SIGN(key);
584 sig.siglen = siglen;
585
586 return ltree_execute(GETQUERY(query),
587 &sig, false,
589}
590
591static bool
592arrq_cons(ltree_gist *key, ArrayType *_query, int siglen)
593{
594 lquery *query = (lquery *) ARR_DATA_PTR(_query);
595 int num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
596
597 if (ARR_NDIM(_query) > 1)
599 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
600 errmsg("array must be one-dimensional")));
601 if (array_contains_nulls(_query))
603 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
604 errmsg("array must not contain nulls")));
605
606 while (num > 0)
607 {
608 if (gist_qe(key, query, siglen) && gist_between(key, query, siglen))
609 return true;
610 num--;
611 query = NEXTVAL(query);
612 }
613 return false;
614}
615
616Datum
618{
619 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
621
622 /* Oid subtype = PG_GETARG_OID(3); */
623 bool *recheck = (bool *) PG_GETARG_POINTER(4);
624 int siglen = LTREE_GET_SIGLEN();
626 void *query = NULL;
627 bool res = false;
628
629 /* All cases served by this function are exact */
630 *recheck = false;
631
632 switch (strategy)
633 {
635 query = PG_GETARG_LTREE_P(1);
636 res = (GIST_LEAF(entry)) ?
637 (ltree_compare((ltree *) query, LTG_NODE(key)) > 0)
638 :
639 (ltree_compare((ltree *) query, LTG_GETLNODE(key, siglen)) >= 0);
640 break;
642 query = PG_GETARG_LTREE_P(1);
643 res = (ltree_compare((ltree *) query, LTG_GETLNODE(key, siglen)) >= 0);
644 break;
646 query = PG_GETARG_LTREE_P(1);
647 if (GIST_LEAF(entry))
648 res = (ltree_compare((ltree *) query, LTG_NODE(key)) == 0);
649 else
650 res = (ltree_compare((ltree *) query, LTG_GETLNODE(key, siglen)) >= 0
651 &&
652 ltree_compare((ltree *) query, LTG_GETRNODE(key, siglen)) <= 0);
653 break;
655 query = PG_GETARG_LTREE_P(1);
656 res = (ltree_compare((ltree *) query, LTG_GETRNODE(key, siglen)) <= 0);
657 break;
659 query = PG_GETARG_LTREE_P(1);
660 res = (GIST_LEAF(entry)) ?
661 (ltree_compare((ltree *) query, LTG_GETRNODE(key, siglen)) < 0)
662 :
663 (ltree_compare((ltree *) query, LTG_GETRNODE(key, siglen)) <= 0);
664 break;
665 case 10:
666 query = PG_GETARG_LTREE_P_COPY(1);
667 res = (GIST_LEAF(entry)) ?
668 inner_isparent((ltree *) query, LTG_NODE(key))
669 :
670 gist_isparent(key, (ltree *) query, siglen);
671 break;
672 case 11:
673 query = PG_GETARG_LTREE_P(1);
674 res = (GIST_LEAF(entry)) ?
675 inner_isparent(LTG_NODE(key), (ltree *) query)
676 :
677 gist_ischild(key, (ltree *) query, siglen);
678 break;
679 case 12:
680 case 13:
681 query = PG_GETARG_LQUERY_P(1);
682 if (GIST_LEAF(entry))
685 PointerGetDatum((lquery *) query)
686 ));
687 else
688 res = (gist_qe(key, (lquery *) query, siglen) &&
689 gist_between(key, (lquery *) query, siglen));
690 break;
691 case 14:
692 case 15:
693 query = PG_GETARG_LTXTQUERY_P(1);
694 if (GIST_LEAF(entry))
697 PointerGetDatum((ltxtquery *) query)
698 ));
699 else
700 res = gist_qtxt(key, (ltxtquery *) query, siglen);
701 break;
702 case 16:
703 case 17:
704 query = PG_GETARG_ARRAYTYPE_P(1);
705 if (GIST_LEAF(entry))
708 PointerGetDatum((ArrayType *) query)
709 ));
710 else
711 res = arrq_cons(key, (ArrayType *) query, siglen);
712 break;
713 default:
714 /* internal error */
715 elog(ERROR, "unrecognized StrategyNumber: %d", strategy);
716 }
717
718 PG_FREE_IF_COPY(query, 1);
720}
721
722static void
723ltree_gist_relopts_validator(void *parsed_options, relopt_value *vals,
724 int nvals)
725{
726 LtreeGistOptions *options = (LtreeGistOptions *) parsed_options;
727
728 if (options->siglen != INTALIGN(options->siglen))
730 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
731 errmsg("siglen value must be a multiple of %d", ALIGNOF_INT)));
732}
733
734Datum
736{
738
739 init_local_reloptions(relopts, sizeof(LtreeGistOptions));
740 add_local_int_reloption(relopts, "siglen",
741 "signature length in bytes",
743 INTALIGN(1),
745 offsetof(LtreeGistOptions, siglen));
747
749}
#define GETQUERY(x)
Definition: _int.h:157
#define ARR_NDIM(a)
Definition: array.h:290
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:263
#define ARR_DATA_PTR(a)
Definition: array.h:322
#define ARR_DIMS(a)
Definition: array.h:294
bool array_contains_nulls(ArrayType *array)
Definition: arrayfuncs.c:3767
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:57
#define GETBIT(x, i)
Definition: blutils.c:30
#define Min(x, y)
Definition: c.h:961
#define INTALIGN(LEN)
Definition: c.h:765
#define Max(x, y)
Definition: c.h:955
#define Assert(condition)
Definition: c.h:815
int32_t int32
Definition: c.h:484
unsigned int ltree_crc32_sz(const char *buf, int size)
Definition: crc32.c:24
struct cursor * cur
Definition: ecpg.c:29
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define ereport(elevel,...)
Definition: elog.h:149
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:643
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:272
#define PG_DETOAST_DATUM(datum)
Definition: fmgr.h:240
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define GIST_LEAF(entry)
Definition: gist.h:171
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:245
#define newval
#define HASHVAL(val, siglen)
Definition: hstore_gist.c:45
#define LOOPBYTE(siglen)
Definition: hstore_gist.c:33
char * BITVECP
Definition: hstore_gist.c:31
#define HASH(sign, val, siglen)
Definition: hstore_gist.c:46
long val
Definition: informix.c:689
char sign
Definition: informix.c:693
int b
Definition: isn.c:69
int a
Definition: isn.c:68
int j
Definition: isn.c:73
int i
Definition: isn.c:72
Datum lt_q_regex(PG_FUNCTION_ARGS)
Definition: lquery_op.c:239
Datum ltq_regex(PG_FUNCTION_ARGS)
Definition: lquery_op.c:215
#define LTG_HDRSIZE
Definition: ltree.h:277
bool inner_isparent(const ltree *c, const ltree *p)
Definition: ltree_op.c:210
#define DatumGetLtreeP(X)
Definition: ltree.h:216
#define FLG_CANLOOKSIGN(x)
Definition: ltree.h:107
#define PG_GETARG_LTXTQUERY_P(n)
Definition: ltree.h:228
#define LTREE_SIGLEN_MAX
Definition: ltree.h:236
PGDLLEXPORT Datum ltxtq_exec(PG_FUNCTION_ARGS)
Definition: ltxtquery_op.c:84
#define LTREE_FIRST(x)
Definition: ltree.h:51
#define LTG_RNODE(x, siglen)
Definition: ltree.h:285
#define PG_GETARG_LQUERY_P(n)
Definition: ltree.h:223
#define LTG_ONENODE
Definition: ltree.h:273
#define LTG_ALLTRUE
Definition: ltree.h:274
#define LEVEL_NEXT(x)
Definition: ltree.h:40
#define LTG_GETRNODE(x, siglen)
Definition: ltree.h:288
int ltree_compare(const ltree *a, const ltree *b)
Definition: ltree_op.c:43
#define LTG_NORIGHT
Definition: ltree.h:275
#define LTREE_GET_SIGLEN()
Definition: ltree.h:237
bool ltree_execute(ITEM *curitem, void *checkval, bool calcnot, bool(*chkcond)(void *checkval, ITEM *val))
Definition: ltxtquery_op.c:20
#define PG_GETARG_LTREE_P_COPY(n)
Definition: ltree.h:219
#define LQL_CANLOOKSIGN(x)
Definition: ltree.h:111
#define LQL_FIRST(x)
Definition: ltree.h:101
#define LVAR_NEXT(x)
Definition: ltree.h:72
#define LQL_NEXT(x)
Definition: ltree.h:100
#define LQUERY_FIRST(x)
Definition: ltree.h:124
#define LTREE_SIGLEN_DEFAULT
Definition: ltree.h:235
#define LTG_ISALLTRUE(x)
Definition: ltree.h:281
#define LTG_SIGN(x)
Definition: ltree.h:278
#define LTG_ISONENODE(x)
Definition: ltree.h:280
#define LTG_LNODE(x, siglen)
Definition: ltree.h:283
#define PG_GETARG_LTREE_P(n)
Definition: ltree.h:218
#define LTG_GETLNODE(x, siglen)
Definition: ltree.h:287
#define LTG_NODE(x)
Definition: ltree.h:279
Datum ltree_same(PG_FUNCTION_ARGS)
Definition: ltree_gist.c:131
Datum ltree_picksplit(PG_FUNCTION_ARGS)
Definition: ltree_gist.c:294
#define NEXTVAL(x)
Definition: ltree_gist.c:15
static bool gist_qe(ltree_gist *key, lquery *query, int siglen)
Definition: ltree_gist.c:479
Datum ltree_union(PG_FUNCTION_ARGS)
Definition: ltree_gist.c:192
Datum ltree_gist_options(PG_FUNCTION_ARGS)
Definition: ltree_gist.c:735
Datum ltree_compress(PG_FUNCTION_ARGS)
Definition: ltree_gist.c:94
static void hashing(BITVECP sign, ltree *t, int siglen)
Definition: ltree_gist.c:176
static bool gist_ischild(ltree_gist *key, ltree *query, int siglen)
Definition: ltree_gist.c:454
static int gist_tqcmp(ltree *t, lquery *q)
Definition: ltree_gist.c:518
static void ltree_gist_relopts_validator(void *parsed_options, relopt_value *vals, int nvals)
Definition: ltree_gist.c:723
#define GETENTRY(vec, pos)
Definition: ltree_gist.c:91
Datum ltree_penalty(PG_FUNCTION_ARGS)
Definition: ltree_gist.c:261
static bool gist_qtxt(ltree_gist *key, ltxtquery *query, int siglen)
Definition: ltree_gist.c:576
Datum ltree_gist_in(PG_FUNCTION_ARGS)
Definition: ltree_gist.c:22
Datum ltree_gist_out(PG_FUNCTION_ARGS)
Definition: ltree_gist.c:32
static bool gist_between(ltree_gist *key, lquery *query, int siglen)
Definition: ltree_gist.c:547
struct LtreeSignature LtreeSignature
static bool arrq_cons(ltree_gist *key, ArrayType *_query, int siglen)
Definition: ltree_gist.c:592
PG_FUNCTION_INFO_V1(ltree_gist_in)
static bool gist_isparent(ltree_gist *key, ltree *query, int siglen)
Definition: ltree_gist.c:424
Datum ltree_decompress(PG_FUNCTION_ARGS)
Definition: ltree_gist.c:113
static int treekey_cmp(const void *a, const void *b)
Definition: ltree_gist.c:286
static bool checkcondition_bit(void *cxt, ITEM *val)
Definition: ltree_gist.c:568
struct rix RIX
Datum ltree_consistent(PG_FUNCTION_ARGS)
Definition: ltree_gist.c:617
#define ISEQ(a, b)
Definition: ltree_gist.c:16
static ltree * copy_ltree(ltree *src)
Definition: ltree_gist.c:445
ltree_gist * ltree_gist_alloc(bool isalltrue, BITVECP sign, int siglen, ltree *left, ltree *right)
Definition: ltree_gist.c:42
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc0(Size size)
Definition: mcxt.c:1347
void * palloc(Size size)
Definition: mcxt.c:1317
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
uint16 OffsetNumber
Definition: off.h:24
#define FirstOffsetNumber
Definition: off.h:27
static int sig
Definition: pg_ctl.c:80
#define qsort(a, b, c, d)
Definition: port.h:475
static bool DatumGetBool(Datum X)
Definition: postgres.h:95
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
uintptr_t Datum
Definition: postgres.h:69
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:317
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:715
void init_local_reloptions(local_relopts *relopts, Size relopt_struct_size)
Definition: reloptions.c:753
void register_reloptions_validator(local_relopts *relopts, relopts_validator validator)
Definition: reloptions.c:766
void add_local_int_reloption(local_relopts *relopts, const char *name, const char *desc, int default_val, int min_val, int max_val, int offset)
Definition: reloptions.c:937
static pg_noinline void Size size
Definition: slab.c:607
uint16 StrategyNumber
Definition: stratnum.h:22
#define BTGreaterStrategyNumber
Definition: stratnum.h:33
#define BTLessStrategyNumber
Definition: stratnum.h:29
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define BTLessEqualStrategyNumber
Definition: stratnum.h:30
#define BTGreaterEqualStrategyNumber
Definition: stratnum.h:32
OffsetNumber offset
Definition: gist.h:164
Datum key
Definition: gist.h:161
Page page
Definition: gist.h:163
Relation rel
Definition: gist.h:162
bool leafkey
Definition: gist.h:165
int spl_nleft
Definition: gist.h:144
OffsetNumber * spl_right
Definition: gist.h:148
Datum spl_ldatum
Definition: gist.h:145
Datum spl_rdatum
Definition: gist.h:150
int spl_nright
Definition: gist.h:149
OffsetNumber * spl_left
Definition: gist.h:143
int32 n
Definition: gist.h:236
Definition: _int.h:141
char * name
Definition: type.h:139
Definition: type.h:96
uint16 numvar
Definition: ltree.h:92
int32 val
Definition: ltree.h:60
uint16 len
Definition: ltree.h:61
char name[FLEXIBLE_ARRAY_MEMBER]
Definition: ltree.h:63
Definition: ltree.h:114
uint16 firstgood
Definition: ltree.h:117
uint16 numlevel
Definition: ltree.h:116
uint32 flag
Definition: ltree.h:269
char name[FLEXIBLE_ARRAY_MEMBER]
Definition: ltree.h:36
uint16 len
Definition: ltree.h:35
Definition: ltree.h:43
uint16 numlevel
Definition: ltree.h:45
ltree * r
Definition: ltree_gist.c:282
int index
Definition: ltree_gist.c:281
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305
#define VARSIZE(PTR)
Definition: varatt.h:279