PostgreSQL Source Code  git master
tsgistidx.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * tsgistidx.c
4  * GiST support functions for tsvector_ops
5  *
6  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
7  *
8  *
9  * IDENTIFICATION
10  * src/backend/utils/adt/tsgistidx.c
11  *
12  *-------------------------------------------------------------------------
13  */
14 
15 #include "postgres.h"
16 
17 #include "access/gist.h"
18 #include "access/heaptoast.h"
19 #include "access/reloptions.h"
20 #include "lib/qunique.h"
21 #include "port/pg_bitutils.h"
22 #include "tsearch/ts_utils.h"
23 #include "utils/builtins.h"
24 #include "utils/pg_crc.h"
25 
26 
27 /* tsvector_ops opclass options */
28 typedef struct
29 {
30  int32 vl_len_; /* varlena header (do not touch directly!) */
31  int siglen; /* signature length */
33 
34 #define SIGLEN_DEFAULT (31 * 4)
35 #define SIGLEN_MAX GISTMaxIndexKeySize
36 #define GET_SIGLEN() (PG_HAS_OPCLASS_OPTIONS() ? \
37  ((GistTsVectorOptions *) PG_GET_OPCLASS_OPTIONS())->siglen : \
38  SIGLEN_DEFAULT)
39 
40 #define SIGLENBIT(siglen) ((siglen) * BITS_PER_BYTE)
41 
42 typedef char *BITVECP;
43 
44 #define LOOPBYTE(siglen) \
45  for (i = 0; i < siglen; i++)
46 
47 #define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITS_PER_BYTE ) ) )
48 #define GETBITBYTE(x,i) ( ((char)(x)) >> (i) & 0x01 )
49 #define CLRBIT(x,i) GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITS_PER_BYTE ) )
50 #define SETBIT(x,i) GETBYTE(x,i) |= ( 0x01 << ( (i) % BITS_PER_BYTE ) )
51 #define GETBIT(x,i) ( (GETBYTE(x,i) >> ( (i) % BITS_PER_BYTE )) & 0x01 )
52 
53 #define HASHVAL(val, siglen) (((unsigned int)(val)) % SIGLENBIT(siglen))
54 #define HASH(sign, val, siglen) SETBIT((sign), HASHVAL(val, siglen))
55 
56 #define GETENTRY(vec,pos) ((SignTSVector *) DatumGetPointer((vec)->vector[(pos)].key))
57 
58 /*
59  * type of GiST index key
60  */
61 
62 typedef struct
63 {
64  int32 vl_len_; /* varlena header (do not touch directly!) */
67 } SignTSVector;
68 
69 #define ARRKEY 0x01
70 #define SIGNKEY 0x02
71 #define ALLISTRUE 0x04
72 
73 #define ISARRKEY(x) ( ((SignTSVector*)(x))->flag & ARRKEY )
74 #define ISSIGNKEY(x) ( ((SignTSVector*)(x))->flag & SIGNKEY )
75 #define ISALLTRUE(x) ( ((SignTSVector*)(x))->flag & ALLISTRUE )
76 
77 #define GTHDRSIZE ( VARHDRSZ + sizeof(int32) )
78 #define CALCGTSIZE(flag, len) ( GTHDRSIZE + ( ( (flag) & ARRKEY ) ? ((len)*sizeof(int32)) : (((flag) & ALLISTRUE) ? 0 : (len)) ) )
79 
80 #define GETSIGN(x) ( (BITVECP)( (char*)(x)+GTHDRSIZE ) )
81 #define GETSIGLEN(x)( VARSIZE(x) - GTHDRSIZE )
82 #define GETARR(x) ( (int32*)( (char*)(x)+GTHDRSIZE ) )
83 #define ARRNELEM(x) ( ( VARSIZE(x) - GTHDRSIZE )/sizeof(int32) )
84 
85 static int32 sizebitvec(BITVECP sign, int siglen);
86 
87 Datum
89 {
90  /* There's no need to support input of gtsvectors */
91  ereport(ERROR,
92  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
93  errmsg("cannot accept a value of type %s", "gtsvector")));
94 
95  PG_RETURN_VOID(); /* keep compiler quiet */
96 }
97 
98 #define SINGOUTSTR "%d true bits, %d false bits"
99 #define ARROUTSTR "%d unique words"
100 #define EXTRALEN ( 2*13 )
101 
102 static int outbuf_maxlen = 0;
103 
104 Datum
106 {
108  char *outbuf;
109 
110  if (outbuf_maxlen == 0)
111  outbuf_maxlen = 2 * EXTRALEN + Max(strlen(SINGOUTSTR), strlen(ARROUTSTR)) + 1;
112  outbuf = palloc(outbuf_maxlen);
113 
114  if (ISARRKEY(key))
115  sprintf(outbuf, ARROUTSTR, (int) ARRNELEM(key));
116  else
117  {
118  if (ISALLTRUE(key))
119  sprintf(outbuf, "all true bits");
120  else
121  {
122  int siglen = GETSIGLEN(key);
123  int cnttrue = sizebitvec(GETSIGN(key), siglen);
124 
125  sprintf(outbuf, SINGOUTSTR, cnttrue, (int) SIGLENBIT(siglen) - cnttrue);
126  }
127  }
128 
129  PG_FREE_IF_COPY(key, 0);
130  PG_RETURN_POINTER(outbuf);
131 }
132 
133 static int
134 compareint(const void *va, const void *vb)
135 {
136  int32 a = *((const int32 *) va);
137  int32 b = *((const int32 *) vb);
138 
139  if (a == b)
140  return 0;
141  return (a > b) ? 1 : -1;
142 }
143 
144 static void
146 {
147  int32 k,
148  len = ARRNELEM(a);
149  int32 *ptr = GETARR(a);
150 
151  MemSet(sign, 0, siglen);
152  for (k = 0; k < len; k++)
153  HASH(sign, ptr[k], siglen);
154 }
155 
156 static SignTSVector *
158 {
159  int size = CALCGTSIZE(flag, len);
160  SignTSVector *res = palloc(size);
161 
162  SET_VARSIZE(res, size);
163  res->flag = flag;
164 
165  if ((flag & (SIGNKEY | ALLISTRUE)) == SIGNKEY && sign)
166  memcpy(GETSIGN(res), sign, len);
167 
168  return res;
169 }
170 
171 
172 Datum
174 {
175  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
176  int siglen = GET_SIGLEN();
177  GISTENTRY *retval = entry;
178 
179  if (entry->leafkey)
180  { /* tsvector */
181  TSVector val = DatumGetTSVector(entry->key);
182  SignTSVector *res = gtsvector_alloc(ARRKEY, val->size, NULL);
183  int32 len;
184  int32 *arr;
185  WordEntry *ptr = ARRPTR(val);
186  char *words = STRPTR(val);
187 
188  arr = GETARR(res);
189  len = val->size;
190  while (len--)
191  {
192  pg_crc32 c;
193 
195  COMP_LEGACY_CRC32(c, words + ptr->pos, ptr->len);
197 
198  *arr = *(int32 *) &c;
199  arr++;
200  ptr++;
201  }
202 
203  qsort(GETARR(res), val->size, sizeof(int), compareint);
204  len = qunique(GETARR(res), val->size, sizeof(int), compareint);
205  if (len != val->size)
206  {
207  /*
208  * there is a collision of hash-function; len is always less than
209  * val->size
210  */
211  len = CALCGTSIZE(ARRKEY, len);
212  res = (SignTSVector *) repalloc(res, len);
213  SET_VARSIZE(res, len);
214  }
215 
216  /* make signature, if array is too long */
218  {
219  SignTSVector *ressign = gtsvector_alloc(SIGNKEY, siglen, NULL);
220 
221  makesign(GETSIGN(ressign), res, siglen);
222  res = ressign;
223  }
224 
225  retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
227  entry->rel, entry->page,
228  entry->offset, false);
229  }
230  else if (ISSIGNKEY(DatumGetPointer(entry->key)) &&
231  !ISALLTRUE(DatumGetPointer(entry->key)))
232  {
233  int32 i;
234  SignTSVector *res;
236 
237  LOOPBYTE(siglen)
238  {
239  if ((sign[i] & 0xff) != 0xff)
240  PG_RETURN_POINTER(retval);
241  }
242 
243  res = gtsvector_alloc(SIGNKEY | ALLISTRUE, siglen, sign);
244  retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
246  entry->rel, entry->page,
247  entry->offset, false);
248  }
249  PG_RETURN_POINTER(retval);
250 }
251 
252 Datum
254 {
255  /*
256  * We need to detoast the stored value, because the other gtsvector
257  * support functions don't cope with toasted values.
258  */
259  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
261 
262  if (key != (SignTSVector *) DatumGetPointer(entry->key))
263  {
264  GISTENTRY *retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
265 
267  entry->rel, entry->page,
268  entry->offset, false);
269 
270  PG_RETURN_POINTER(retval);
271  }
272 
273  PG_RETURN_POINTER(entry);
274 }
275 
276 typedef struct
277 {
278  int32 *arrb;
279  int32 *arre;
280 } CHKVAL;
281 
282 /*
283  * TS_execute callback for matching a tsquery operand to GIST leaf-page data
284  */
285 static TSTernaryValue
287 {
288  int32 *StopLow = ((CHKVAL *) checkval)->arrb;
289  int32 *StopHigh = ((CHKVAL *) checkval)->arre;
290  int32 *StopMiddle;
291 
292  /* Loop invariant: StopLow <= val < StopHigh */
293 
294  /*
295  * we are not able to find a prefix by hash value
296  */
297  if (val->prefix)
298  return TS_MAYBE;
299 
300  while (StopLow < StopHigh)
301  {
302  StopMiddle = StopLow + (StopHigh - StopLow) / 2;
303  if (*StopMiddle == val->valcrc)
304  return TS_MAYBE;
305  else if (*StopMiddle < val->valcrc)
306  StopLow = StopMiddle + 1;
307  else
308  StopHigh = StopMiddle;
309  }
310 
311  return TS_NO;
312 }
313 
314 /*
315  * TS_execute callback for matching a tsquery operand to GIST non-leaf data
316  */
317 static TSTernaryValue
319 {
320  void *key = (SignTSVector *) checkval;
321 
322  /*
323  * we are not able to find a prefix in signature tree
324  */
325  if (val->prefix)
326  return TS_MAYBE;
327 
328  if (GETBIT(GETSIGN(key), HASHVAL(val->valcrc, GETSIGLEN(key))))
329  return TS_MAYBE;
330  else
331  return TS_NO;
332 }
333 
334 Datum
336 {
337  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
338  TSQuery query = PG_GETARG_TSQUERY(1);
339 
340  /* StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); */
341  /* Oid subtype = PG_GETARG_OID(3); */
342  bool *recheck = (bool *) PG_GETARG_POINTER(4);
344 
345  /* All cases served by this function are inexact */
346  *recheck = true;
347 
348  if (!query->size)
349  PG_RETURN_BOOL(false);
350 
351  if (ISSIGNKEY(key))
352  {
353  if (ISALLTRUE(key))
354  PG_RETURN_BOOL(true);
355 
357  key,
360  }
361  else
362  { /* only leaf pages */
363  CHKVAL chkval;
364 
365  chkval.arrb = GETARR(key);
366  chkval.arre = chkval.arrb + ARRNELEM(key);
368  (void *) &chkval,
371  }
372 }
373 
374 static int32
375 unionkey(BITVECP sbase, SignTSVector *add, int siglen)
376 {
377  int32 i;
378 
379  if (ISSIGNKEY(add))
380  {
381  BITVECP sadd = GETSIGN(add);
382 
383  if (ISALLTRUE(add))
384  return 1;
385 
386  Assert(GETSIGLEN(add) == siglen);
387 
388  LOOPBYTE(siglen)
389  sbase[i] |= sadd[i];
390  }
391  else
392  {
393  int32 *ptr = GETARR(add);
394 
395  for (i = 0; i < ARRNELEM(add); i++)
396  HASH(sbase, ptr[i], siglen);
397  }
398  return 0;
399 }
400 
401 
402 Datum
404 {
406  int *size = (int *) PG_GETARG_POINTER(1);
407  int siglen = GET_SIGLEN();
408  SignTSVector *result = gtsvector_alloc(SIGNKEY, siglen, NULL);
409  BITVECP base = GETSIGN(result);
410  int32 i;
411 
412  memset(base, 0, siglen);
413 
414  for (i = 0; i < entryvec->n; i++)
415  {
416  if (unionkey(base, GETENTRY(entryvec, i), siglen))
417  {
418  result->flag |= ALLISTRUE;
419  SET_VARSIZE(result, CALCGTSIZE(result->flag, siglen));
420  break;
421  }
422  }
423 
424  *size = VARSIZE(result);
425 
426  PG_RETURN_POINTER(result);
427 }
428 
429 Datum
431 {
434  bool *result = (bool *) PG_GETARG_POINTER(2);
435  int siglen = GET_SIGLEN();
436 
437  if (ISSIGNKEY(a))
438  { /* then b also ISSIGNKEY */
439  if (ISALLTRUE(a) && ISALLTRUE(b))
440  *result = true;
441  else if (ISALLTRUE(a))
442  *result = false;
443  else if (ISALLTRUE(b))
444  *result = false;
445  else
446  {
447  int32 i;
448  BITVECP sa = GETSIGN(a),
449  sb = GETSIGN(b);
450 
451  Assert(GETSIGLEN(a) == siglen && GETSIGLEN(b) == siglen);
452 
453  *result = true;
454  LOOPBYTE(siglen)
455  {
456  if (sa[i] != sb[i])
457  {
458  *result = false;
459  break;
460  }
461  }
462  }
463  }
464  else
465  { /* a and b ISARRKEY */
466  int32 lena = ARRNELEM(a),
467  lenb = ARRNELEM(b);
468 
469  if (lena != lenb)
470  *result = false;
471  else
472  {
473  int32 *ptra = GETARR(a),
474  *ptrb = GETARR(b);
475  int32 i;
476 
477  *result = true;
478  for (i = 0; i < lena; i++)
479  if (ptra[i] != ptrb[i])
480  {
481  *result = false;
482  break;
483  }
484  }
485  }
486 
487  PG_RETURN_POINTER(result);
488 }
489 
490 static int32
491 sizebitvec(BITVECP sign, int siglen)
492 {
493  return pg_popcount(sign, siglen);
494 }
495 
496 static int
498 {
499  int i,
500  diff,
501  dist = 0;
502 
503  LOOPBYTE(siglen)
504  {
505  diff = (unsigned char) (a[i] ^ b[i]);
506  /* Using the popcount functions here isn't likely to win */
507  dist += pg_number_of_ones[diff];
508  }
509  return dist;
510 }
511 
512 static int
514 {
515  int siglena = GETSIGLEN(a);
516  int siglenb = GETSIGLEN(b);
517 
518  if (ISALLTRUE(a))
519  {
520  if (ISALLTRUE(b))
521  return 0;
522  else
523  return SIGLENBIT(siglenb) - sizebitvec(GETSIGN(b), siglenb);
524  }
525  else if (ISALLTRUE(b))
526  return SIGLENBIT(siglena) - sizebitvec(GETSIGN(a), siglena);
527 
528  Assert(siglena == siglenb);
529 
530  return hemdistsign(GETSIGN(a), GETSIGN(b), siglena);
531 }
532 
533 Datum
535 {
536  GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */
537  GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
538  float *penalty = (float *) PG_GETARG_POINTER(2);
539  int siglen = GET_SIGLEN();
540  SignTSVector *origval = (SignTSVector *) DatumGetPointer(origentry->key);
542  BITVECP orig = GETSIGN(origval);
543 
544  *penalty = 0.0;
545 
546  if (ISARRKEY(newval))
547  {
548  BITVECP sign = palloc(siglen);
549 
550  makesign(sign, newval, siglen);
551 
552  if (ISALLTRUE(origval))
553  {
554  int siglenbit = SIGLENBIT(siglen);
555 
556  *penalty =
557  (float) (siglenbit - sizebitvec(sign, siglen)) /
558  (float) (siglenbit + 1);
559  }
560  else
561  *penalty = hemdistsign(sign, orig, siglen);
562 
563  pfree(sign);
564  }
565  else
566  *penalty = hemdist(origval, newval);
567  PG_RETURN_POINTER(penalty);
568 }
569 
570 typedef struct
571 {
572  bool allistrue;
573  BITVECP sign;
574 } CACHESIGN;
575 
576 static void
577 fillcache(CACHESIGN *item, SignTSVector *key, int siglen)
578 {
579  item->allistrue = false;
580  if (ISARRKEY(key))
581  makesign(item->sign, key, siglen);
582  else if (ISALLTRUE(key))
583  item->allistrue = true;
584  else
585  memcpy(item->sign, GETSIGN(key), siglen);
586 }
587 
588 #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
589 typedef struct
590 {
591  OffsetNumber pos;
592  int32 cost;
593 } SPLITCOST;
594 
595 static int
596 comparecost(const void *va, const void *vb)
597 {
598  const SPLITCOST *a = (const SPLITCOST *) va;
599  const SPLITCOST *b = (const SPLITCOST *) vb;
600 
601  if (a->cost == b->cost)
602  return 0;
603  else
604  return (a->cost > b->cost) ? 1 : -1;
605 }
606 
607 
608 static int
610 {
611  if (a->allistrue)
612  {
613  if (b->allistrue)
614  return 0;
615  else
616  return SIGLENBIT(siglen) - sizebitvec(b->sign, siglen);
617  }
618  else if (b->allistrue)
619  return SIGLENBIT(siglen) - sizebitvec(a->sign, siglen);
620 
621  return hemdistsign(a->sign, b->sign, siglen);
622 }
623 
624 Datum
626 {
629  int siglen = GET_SIGLEN();
630  OffsetNumber k,
631  j;
632  SignTSVector *datum_l,
633  *datum_r;
634  BITVECP union_l,
635  union_r;
636  int32 size_alpha,
637  size_beta;
638  int32 size_waste,
639  waste = -1;
640  int32 nbytes;
641  OffsetNumber seed_1 = 0,
642  seed_2 = 0;
643  OffsetNumber *left,
644  *right;
645  OffsetNumber maxoff;
646  BITVECP ptr;
647  int i;
648  CACHESIGN *cache;
649  char *cache_sign;
650  SPLITCOST *costvector;
651 
652  maxoff = entryvec->n - 2;
653  nbytes = (maxoff + 2) * sizeof(OffsetNumber);
654  v->spl_left = (OffsetNumber *) palloc(nbytes);
655  v->spl_right = (OffsetNumber *) palloc(nbytes);
656 
657  cache = (CACHESIGN *) palloc(sizeof(CACHESIGN) * (maxoff + 2));
658  cache_sign = palloc(siglen * (maxoff + 2));
659 
660  for (j = 0; j < maxoff + 2; j++)
661  cache[j].sign = &cache_sign[siglen * j];
662 
664  siglen);
665 
666  for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
667  {
668  for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
669  {
670  if (k == FirstOffsetNumber)
671  fillcache(&cache[j], GETENTRY(entryvec, j), siglen);
672 
673  size_waste = hemdistcache(&(cache[j]), &(cache[k]), siglen);
674  if (size_waste > waste)
675  {
676  waste = size_waste;
677  seed_1 = k;
678  seed_2 = j;
679  }
680  }
681  }
682 
683  left = v->spl_left;
684  v->spl_nleft = 0;
685  right = v->spl_right;
686  v->spl_nright = 0;
687 
688  if (seed_1 == 0 || seed_2 == 0)
689  {
690  seed_1 = 1;
691  seed_2 = 2;
692  }
693 
694  /* form initial .. */
695  datum_l = gtsvector_alloc(SIGNKEY | (cache[seed_1].allistrue ? ALLISTRUE : 0),
696  siglen, cache[seed_1].sign);
697  datum_r = gtsvector_alloc(SIGNKEY | (cache[seed_2].allistrue ? ALLISTRUE : 0),
698  siglen, cache[seed_2].sign);
699  union_l = GETSIGN(datum_l);
700  union_r = GETSIGN(datum_r);
701  maxoff = OffsetNumberNext(maxoff);
702  fillcache(&cache[maxoff], GETENTRY(entryvec, maxoff), siglen);
703  /* sort before ... */
704  costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
705  for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
706  {
707  costvector[j - 1].pos = j;
708  size_alpha = hemdistcache(&(cache[seed_1]), &(cache[j]), siglen);
709  size_beta = hemdistcache(&(cache[seed_2]), &(cache[j]), siglen);
710  costvector[j - 1].cost = abs(size_alpha - size_beta);
711  }
712  qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
713 
714  for (k = 0; k < maxoff; k++)
715  {
716  j = costvector[k].pos;
717  if (j == seed_1)
718  {
719  *left++ = j;
720  v->spl_nleft++;
721  continue;
722  }
723  else if (j == seed_2)
724  {
725  *right++ = j;
726  v->spl_nright++;
727  continue;
728  }
729 
730  if (ISALLTRUE(datum_l) || cache[j].allistrue)
731  {
732  if (ISALLTRUE(datum_l) && cache[j].allistrue)
733  size_alpha = 0;
734  else
735  size_alpha = SIGLENBIT(siglen) -
736  sizebitvec((cache[j].allistrue) ?
737  GETSIGN(datum_l) :
738  cache[j].sign,
739  siglen);
740  }
741  else
742  size_alpha = hemdistsign(cache[j].sign, GETSIGN(datum_l), siglen);
743 
744  if (ISALLTRUE(datum_r) || cache[j].allistrue)
745  {
746  if (ISALLTRUE(datum_r) && cache[j].allistrue)
747  size_beta = 0;
748  else
749  size_beta = SIGLENBIT(siglen) -
750  sizebitvec((cache[j].allistrue) ?
751  GETSIGN(datum_r) :
752  cache[j].sign,
753  siglen);
754  }
755  else
756  size_beta = hemdistsign(cache[j].sign, GETSIGN(datum_r), siglen);
757 
758  if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.1))
759  {
760  if (ISALLTRUE(datum_l) || cache[j].allistrue)
761  {
762  if (!ISALLTRUE(datum_l))
763  memset(GETSIGN(datum_l), 0xff, siglen);
764  }
765  else
766  {
767  ptr = cache[j].sign;
768  LOOPBYTE(siglen)
769  union_l[i] |= ptr[i];
770  }
771  *left++ = j;
772  v->spl_nleft++;
773  }
774  else
775  {
776  if (ISALLTRUE(datum_r) || cache[j].allistrue)
777  {
778  if (!ISALLTRUE(datum_r))
779  memset(GETSIGN(datum_r), 0xff, siglen);
780  }
781  else
782  {
783  ptr = cache[j].sign;
784  LOOPBYTE(siglen)
785  union_r[i] |= ptr[i];
786  }
787  *right++ = j;
788  v->spl_nright++;
789  }
790  }
791 
792  *right = *left = FirstOffsetNumber;
793  v->spl_ldatum = PointerGetDatum(datum_l);
794  v->spl_rdatum = PointerGetDatum(datum_r);
795 
797 }
798 
799 /*
800  * Formerly, gtsvector_consistent was declared in pg_proc.h with arguments
801  * that did not match the documented conventions for GiST support functions.
802  * We fixed that, but we still need a pg_proc entry with the old signature
803  * to support reloading pre-9.6 contrib/tsearch2 opclass declarations.
804  * This compatibility function should go away eventually.
805  */
806 Datum
808 {
809  return gtsvector_consistent(fcinfo);
810 }
811 
812 Datum
814 {
816 
817  init_local_reloptions(relopts, sizeof(GistTsVectorOptions));
818  add_local_int_reloption(relopts, "siglen", "signature length",
820  offsetof(GistTsVectorOptions, siglen));
821 
822  PG_RETURN_VOID();
823 }
#define GETQUERY(x)
Definition: _int.h:157
signed int int32
Definition: c.h:483
#define Max(x, y)
Definition: c.h:987
#define FLEXIBLE_ARRAY_MEMBER
Definition: c.h:387
#define MemSet(start, val, len)
Definition: c.h:1009
#define ARRPTR(x)
Definition: cube.c:25
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#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 PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#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 gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:242
#define newval
#define TOAST_INDEX_TARGET
Definition: heaptoast.h:68
#define STRPTR(x)
Definition: hstore.h:76
char * BITVECP
Definition: hstore_gist.c:30
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')
void pfree(void *pointer)
Definition: mcxt.c:1456
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1476
void * palloc(Size size)
Definition: mcxt.c:1226
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
uint16 OffsetNumber
Definition: off.h:24
#define FirstOffsetNumber
Definition: off.h:27
PGDLLIMPORT const uint8 pg_number_of_ones[256]
Definition: pg_bitutils.c:87
uint64 pg_popcount(const char *buf, int bytes)
Definition: pg_bitutils.c:296
const void size_t len
const void * data
uint32 pg_crc32
Definition: pg_crc.h:37
#define INIT_LEGACY_CRC32(crc)
Definition: pg_crc.h:79
#define COMP_LEGACY_CRC32(crc, data, len)
Definition: pg_crc.h:81
#define FIN_LEGACY_CRC32(crc)
Definition: pg_crc.h:80
#define sprintf
Definition: port.h:240
#define qsort(a, b, c, d)
Definition: port.h:445
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
char * c
static size_t qunique(void *array, size_t elements, size_t width, int(*compare)(const void *, const void *))
Definition: qunique.h:21
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
BITVECP sign
Definition: trgm_gist.c:745
bool allistrue
Definition: trgm_gist.c:744
int32 * arrb
Definition: _int_bool.c:226
int32 * arre
Definition: _int_bool.c:227
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
int32 cost
Definition: hstore_gist.c:353
OffsetNumber pos
Definition: hstore_gist.c:352
int32 flag
Definition: tsgistidx.c:65
int32 vl_len_
Definition: tsgistidx.c:64
int32 size
Definition: ts_type.h:221
uint32 pos
Definition: ts_type.h:46
uint32 len
Definition: ts_type.h:45
char * flag(int b)
Definition: test-ctype.c:33
static TSVector DatumGetTSVector(Datum X)
Definition: ts_type.h:118
#define PG_GETARG_TSQUERY(n)
Definition: ts_type.h:266
#define TS_EXEC_PHRASE_NO_POS
Definition: ts_utils.h:202
TSTernaryValue
Definition: ts_utils.h:133
@ TS_MAYBE
Definition: ts_utils.h:136
@ TS_NO
Definition: ts_utils.h:134
static int32 unionkey(BITVECP sbase, SignTSVector *add, int siglen)
Definition: tsgistidx.c:375
#define HASHVAL(val, siglen)
Definition: tsgistidx.c:53
static int hemdistcache(CACHESIGN *a, CACHESIGN *b, int siglen)
Definition: tsgistidx.c:609
#define LOOPBYTE(siglen)
Definition: tsgistidx.c:44
Datum gtsvector_penalty(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:534
#define ALLISTRUE
Definition: tsgistidx.c:71
#define WISH_F(a, b, c)
Definition: tsgistidx.c:588
static int hemdist(SignTSVector *a, SignTSVector *b)
Definition: tsgistidx.c:513
#define GETBIT(x, i)
Definition: tsgistidx.c:51
static TSTernaryValue checkcondition_arr(void *checkval, QueryOperand *val, ExecPhraseData *data)
Definition: tsgistidx.c:286
static int32 sizebitvec(BITVECP sign, int siglen)
Definition: tsgistidx.c:491
#define ARROUTSTR
Definition: tsgistidx.c:99
static int hemdistsign(BITVECP a, BITVECP b, int siglen)
Definition: tsgistidx.c:497
Datum gtsvector_same(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:430
static SignTSVector * gtsvector_alloc(int flag, int len, BITVECP sign)
Definition: tsgistidx.c:157
#define GETENTRY(vec, pos)
Definition: tsgistidx.c:56
Datum gtsvector_picksplit(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:625
#define EXTRALEN
Definition: tsgistidx.c:100
#define ISARRKEY(x)
Definition: tsgistidx.c:73
static void fillcache(CACHESIGN *item, SignTSVector *key, int siglen)
Definition: tsgistidx.c:577
#define ARRNELEM(x)
Definition: tsgistidx.c:83
#define ISALLTRUE(x)
Definition: tsgistidx.c:75
static int comparecost(const void *va, const void *vb)
Definition: tsgistidx.c:596
#define SIGLEN_MAX
Definition: tsgistidx.c:35
#define SIGLEN_DEFAULT
Definition: tsgistidx.c:34
Datum gtsvectorin(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:88
char * BITVECP
Definition: tsgistidx.c:42
#define GET_SIGLEN()
Definition: tsgistidx.c:36
Datum gtsvector_compress(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:173
#define CALCGTSIZE(flag, len)
Definition: tsgistidx.c:78
static int outbuf_maxlen
Definition: tsgistidx.c:102
Datum gtsvector_decompress(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:253
Datum gtsvector_consistent(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:335
#define SIGNKEY
Definition: tsgistidx.c:70
static void makesign(BITVECP sign, SignTSVector *a, int siglen)
Definition: tsgistidx.c:145
#define ISSIGNKEY(x)
Definition: tsgistidx.c:74
Datum gtsvector_options(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:813
Datum gtsvector_union(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:403
Datum gtsvectorout(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:105
#define SIGLENBIT(siglen)
Definition: tsgistidx.c:40
#define GETARR(x)
Definition: tsgistidx.c:82
#define GETSIGLEN(x)
Definition: tsgistidx.c:81
static int compareint(const void *va, const void *vb)
Definition: tsgistidx.c:134
#define ARRKEY
Definition: tsgistidx.c:69
static TSTernaryValue checkcondition_bit(void *checkval, QueryOperand *val, ExecPhraseData *data)
Definition: tsgistidx.c:318
#define GETSIGN(x)
Definition: tsgistidx.c:80
#define HASH(sign, val, siglen)
Definition: tsgistidx.c:54
Datum gtsvector_consistent_oldsig(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:807
#define SINGOUTSTR
Definition: tsgistidx.c:98
bool TS_execute(QueryItem *curitem, void *arg, uint32 flags, TSExecuteCallback chkcond)
Definition: tsvector_op.c:1856
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305
#define VARSIZE(PTR)
Definition: varatt.h:279