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