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 
21 Datum
23 {
24  ereport(ERROR,
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 
31 Datum
33 {
34  ereport(ERROR,
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 
41 ltree_gist *
42 ltree_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 
93 Datum
95 {
96  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
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 
112 Datum
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 
130 Datum
132 {
135  bool *result = (bool *) PG_GETARG_POINTER(2);
136  int siglen = LTREE_GET_SIGLEN();
137 
138  *result = false;
139  if (LTG_ISONENODE(a) != LTG_ISONENODE(b))
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 
150  if (LTG_ISALLTRUE(a) != LTG_ISALLTRUE(b))
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 
175 static void
176 hashing(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 
191 Datum
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 
260 Datum
262 {
263  ltree_gist *origval = (ltree_gist *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
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 */
279 typedef struct rix
280 {
281  int index;
283 } RIX;
284 
285 static int
286 treekey_cmp(const void *a, const void *b)
287 {
288  return ltree_compare(((const RIX *) a)->r,
289  ((const RIX *) b)->r);
290 }
291 
292 
293 Datum
295 {
298  int siglen = LTREE_GET_SIGLEN();
299  OffsetNumber j;
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 
417  v->spl_ldatum = PointerGetDatum(lu);
418  v->spl_rdatum = PointerGetDatum(ru);
419 
421 }
422 
423 static bool
424 gist_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 
444 static ltree *
446 {
447  ltree *dst = (ltree *) palloc0(VARSIZE(src));
448 
449  memcpy(dst, src, VARSIZE(src));
450  return dst;
451 }
452 
453 static bool
454 gist_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 
478 static bool
479 gist_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 
517 static 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 
546 static bool
547 gist_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 
561 typedef struct LtreeSignature
562 {
563  BITVECP sign;
564  int siglen;
566 
567 static bool
569 {
570  LtreeSignature *sig = cxt;
571 
572  return (FLG_CANLOOKSIGN(val->flag)) ? GETBIT(sig->sign, HASHVAL(val->val, sig->siglen)) : true;
573 }
574 
575 static bool
576 gist_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 
591 static bool
592 arrq_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)
598  ereport(ERROR,
599  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
600  errmsg("array must be one-dimensional")));
601  if (array_contains_nulls(_query))
602  ereport(ERROR,
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 
616 Datum
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 
722 static void
723 ltree_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))
729  ereport(ERROR,
730  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
731  errmsg("siglen value must be a multiple of %d", ALIGNOF_INT)));
732 }
733 
734 Datum
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 
748  PG_RETURN_VOID();
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:3755
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:57
#define GETBIT(x, i)
Definition: blutils.c:33
#define Min(x, y)
Definition: c.h:1007
#define INTALIGN(LEN)
Definition: c.h:811
signed int int32
Definition: c.h:497
#define Max(x, y)
Definition: c.h:1001
#define Assert(condition)
Definition: c.h:861
unsigned int ltree_crc32_sz(const char *buf, int size)
Definition: crc32.c:24
struct cursor * cur
Definition: ecpg.c:28
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:170
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:244
#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:70
int a
Definition: isn.c:69
int j
Definition: isn.c:74
int i
Definition: isn.c:73
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:212
#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:45
#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
ltree_gist * ltree_gist_alloc(bool isalltrue, BITVECP sign, int siglen, ltree *left, ltree *right)
Definition: ltree_gist.c:42
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
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:447
static bool DatumGetBool(Datum X)
Definition: postgres.h:90
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
uintptr_t Datum
Definition: postgres.h:64
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
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:734
void register_reloptions_validator(local_relopts *relopts, relopts_validator validator)
Definition: reloptions.c:747
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:918
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:163
Datum key
Definition: gist.h:160
Page page
Definition: gist.h:162
Relation rel
Definition: gist.h:161
bool leafkey
Definition: gist.h:164
int spl_nleft
Definition: gist.h:143
OffsetNumber * spl_right
Definition: gist.h:147
Datum spl_ldatum
Definition: gist.h:144
Datum spl_rdatum
Definition: gist.h:149
int spl_nright
Definition: gist.h:148
OffsetNumber * spl_left
Definition: gist.h:142
int32 n
Definition: gist.h:235
Definition: _int.h:141
char * name
Definition: type.h:138
Definition: type.h:95
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