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  int siglen = GETSIGLEN(key);
119  int cnttrue = (ISALLTRUE(key)) ? SIGLENBIT(siglen) : sizebitvec(GETSIGN(key), siglen);
120 
121  sprintf(outbuf, SINGOUTSTR, cnttrue, (int) SIGLENBIT(siglen) - cnttrue);
122  }
123 
124  PG_FREE_IF_COPY(key, 0);
125  PG_RETURN_POINTER(outbuf);
126 }
127 
128 static int
129 compareint(const void *va, const void *vb)
130 {
131  int32 a = *((const int32 *) va);
132  int32 b = *((const int32 *) vb);
133 
134  if (a == b)
135  return 0;
136  return (a > b) ? 1 : -1;
137 }
138 
139 static void
141 {
142  int32 k,
143  len = ARRNELEM(a);
144  int32 *ptr = GETARR(a);
145 
146  MemSet((void *) sign, 0, siglen);
147  for (k = 0; k < len; k++)
148  HASH(sign, ptr[k], siglen);
149 }
150 
151 static SignTSVector *
153 {
154  int size = CALCGTSIZE(flag, len);
155  SignTSVector *res = palloc(size);
156 
157  SET_VARSIZE(res, size);
158  res->flag = flag;
159 
160  if ((flag & (SIGNKEY | ALLISTRUE)) == SIGNKEY && sign)
161  memcpy(GETSIGN(res), sign, len);
162 
163  return res;
164 }
165 
166 
167 Datum
169 {
170  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
171  int siglen = GET_SIGLEN();
172  GISTENTRY *retval = entry;
173 
174  if (entry->leafkey)
175  { /* tsvector */
176  TSVector val = DatumGetTSVector(entry->key);
177  SignTSVector *res = gtsvector_alloc(ARRKEY, val->size, NULL);
178  int32 len;
179  int32 *arr;
180  WordEntry *ptr = ARRPTR(val);
181  char *words = STRPTR(val);
182 
183  arr = GETARR(res);
184  len = val->size;
185  while (len--)
186  {
187  pg_crc32 c;
188 
190  COMP_LEGACY_CRC32(c, words + ptr->pos, ptr->len);
192 
193  *arr = *(int32 *) &c;
194  arr++;
195  ptr++;
196  }
197 
198  qsort(GETARR(res), val->size, sizeof(int), compareint);
199  len = qunique(GETARR(res), val->size, sizeof(int), compareint);
200  if (len != val->size)
201  {
202  /*
203  * there is a collision of hash-function; len is always less than
204  * val->size
205  */
206  len = CALCGTSIZE(ARRKEY, len);
207  res = (SignTSVector *) repalloc((void *) res, len);
208  SET_VARSIZE(res, len);
209  }
210 
211  /* make signature, if array is too long */
213  {
214  SignTSVector *ressign = gtsvector_alloc(SIGNKEY, siglen, NULL);
215 
216  makesign(GETSIGN(ressign), res, siglen);
217  res = ressign;
218  }
219 
220  retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
222  entry->rel, entry->page,
223  entry->offset, false);
224  }
225  else if (ISSIGNKEY(DatumGetPointer(entry->key)) &&
226  !ISALLTRUE(DatumGetPointer(entry->key)))
227  {
228  int32 i;
229  SignTSVector *res;
231 
232  LOOPBYTE(siglen)
233  {
234  if ((sign[i] & 0xff) != 0xff)
235  PG_RETURN_POINTER(retval);
236  }
237 
238  res = gtsvector_alloc(SIGNKEY | ALLISTRUE, siglen, sign);
239  retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
241  entry->rel, entry->page,
242  entry->offset, false);
243  }
244  PG_RETURN_POINTER(retval);
245 }
246 
247 Datum
249 {
250  /*
251  * We need to detoast the stored value, because the other gtsvector
252  * support functions don't cope with toasted values.
253  */
254  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
256 
257  if (key != (SignTSVector *) DatumGetPointer(entry->key))
258  {
259  GISTENTRY *retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
260 
262  entry->rel, entry->page,
263  entry->offset, false);
264 
265  PG_RETURN_POINTER(retval);
266  }
267 
268  PG_RETURN_POINTER(entry);
269 }
270 
271 typedef struct
272 {
273  int32 *arrb;
274  int32 *arre;
275 } CHKVAL;
276 
277 /*
278  * TS_execute callback for matching a tsquery operand to GIST leaf-page data
279  */
280 static TSTernaryValue
282 {
283  int32 *StopLow = ((CHKVAL *) checkval)->arrb;
284  int32 *StopHigh = ((CHKVAL *) checkval)->arre;
285  int32 *StopMiddle;
286 
287  /* Loop invariant: StopLow <= val < StopHigh */
288 
289  /*
290  * we are not able to find a prefix by hash value
291  */
292  if (val->prefix)
293  return TS_MAYBE;
294 
295  while (StopLow < StopHigh)
296  {
297  StopMiddle = StopLow + (StopHigh - StopLow) / 2;
298  if (*StopMiddle == val->valcrc)
299  return TS_MAYBE;
300  else if (*StopMiddle < val->valcrc)
301  StopLow = StopMiddle + 1;
302  else
303  StopHigh = StopMiddle;
304  }
305 
306  return TS_NO;
307 }
308 
309 /*
310  * TS_execute callback for matching a tsquery operand to GIST non-leaf data
311  */
312 static TSTernaryValue
314 {
315  void *key = (SignTSVector *) checkval;
316 
317  /*
318  * we are not able to find a prefix in signature tree
319  */
320  if (val->prefix)
321  return TS_MAYBE;
322 
323  if (GETBIT(GETSIGN(key), HASHVAL(val->valcrc, GETSIGLEN(key))))
324  return TS_MAYBE;
325  else
326  return TS_NO;
327 }
328 
329 Datum
331 {
332  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
333  TSQuery query = PG_GETARG_TSQUERY(1);
334 
335  /* StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); */
336  /* Oid subtype = PG_GETARG_OID(3); */
337  bool *recheck = (bool *) PG_GETARG_POINTER(4);
339 
340  /* All cases served by this function are inexact */
341  *recheck = true;
342 
343  if (!query->size)
344  PG_RETURN_BOOL(false);
345 
346  if (ISSIGNKEY(key))
347  {
348  if (ISALLTRUE(key))
349  PG_RETURN_BOOL(true);
350 
352  key,
355  }
356  else
357  { /* only leaf pages */
358  CHKVAL chkval;
359 
360  chkval.arrb = GETARR(key);
361  chkval.arre = chkval.arrb + ARRNELEM(key);
363  (void *) &chkval,
366  }
367 }
368 
369 static int32
370 unionkey(BITVECP sbase, SignTSVector *add, int siglen)
371 {
372  int32 i;
373 
374  if (ISSIGNKEY(add))
375  {
376  BITVECP sadd = GETSIGN(add);
377 
378  if (ISALLTRUE(add))
379  return 1;
380 
381  Assert(GETSIGLEN(add) == siglen);
382 
383  LOOPBYTE(siglen)
384  sbase[i] |= sadd[i];
385  }
386  else
387  {
388  int32 *ptr = GETARR(add);
389 
390  for (i = 0; i < ARRNELEM(add); i++)
391  HASH(sbase, ptr[i], siglen);
392  }
393  return 0;
394 }
395 
396 
397 Datum
399 {
401  int *size = (int *) PG_GETARG_POINTER(1);
402  int siglen = GET_SIGLEN();
403  SignTSVector *result = gtsvector_alloc(SIGNKEY, siglen, NULL);
404  BITVECP base = GETSIGN(result);
405  int32 i;
406 
407  memset(base, 0, siglen);
408 
409  for (i = 0; i < entryvec->n; i++)
410  {
411  if (unionkey(base, GETENTRY(entryvec, i), siglen))
412  {
413  result->flag |= ALLISTRUE;
414  SET_VARSIZE(result, CALCGTSIZE(result->flag, siglen));
415  break;
416  }
417  }
418 
419  *size = VARSIZE(result);
420 
421  PG_RETURN_POINTER(result);
422 }
423 
424 Datum
426 {
429  bool *result = (bool *) PG_GETARG_POINTER(2);
430  int siglen = GET_SIGLEN();
431 
432  if (ISSIGNKEY(a))
433  { /* then b also ISSIGNKEY */
434  if (ISALLTRUE(a) && ISALLTRUE(b))
435  *result = true;
436  else if (ISALLTRUE(a))
437  *result = false;
438  else if (ISALLTRUE(b))
439  *result = false;
440  else
441  {
442  int32 i;
443  BITVECP sa = GETSIGN(a),
444  sb = GETSIGN(b);
445 
446  Assert(GETSIGLEN(a) == siglen && GETSIGLEN(b) == siglen);
447 
448  *result = true;
449  LOOPBYTE(siglen)
450  {
451  if (sa[i] != sb[i])
452  {
453  *result = false;
454  break;
455  }
456  }
457  }
458  }
459  else
460  { /* a and b ISARRKEY */
461  int32 lena = ARRNELEM(a),
462  lenb = ARRNELEM(b);
463 
464  if (lena != lenb)
465  *result = false;
466  else
467  {
468  int32 *ptra = GETARR(a),
469  *ptrb = GETARR(b);
470  int32 i;
471 
472  *result = true;
473  for (i = 0; i < lena; i++)
474  if (ptra[i] != ptrb[i])
475  {
476  *result = false;
477  break;
478  }
479  }
480  }
481 
482  PG_RETURN_POINTER(result);
483 }
484 
485 static int32
486 sizebitvec(BITVECP sign, int siglen)
487 {
488  return pg_popcount(sign, siglen);
489 }
490 
491 static int
493 {
494  int i,
495  diff,
496  dist = 0;
497 
498  LOOPBYTE(siglen)
499  {
500  diff = (unsigned char) (a[i] ^ b[i]);
501  /* Using the popcount functions here isn't likely to win */
502  dist += pg_number_of_ones[diff];
503  }
504  return dist;
505 }
506 
507 static int
509 {
510  int siglena = GETSIGLEN(a);
511  int siglenb = GETSIGLEN(b);
512 
513  if (ISALLTRUE(a))
514  {
515  if (ISALLTRUE(b))
516  return 0;
517  else
518  return SIGLENBIT(siglenb) - sizebitvec(GETSIGN(b), siglenb);
519  }
520  else if (ISALLTRUE(b))
521  return SIGLENBIT(siglena) - sizebitvec(GETSIGN(a), siglena);
522 
523  Assert(siglena == siglenb);
524 
525  return hemdistsign(GETSIGN(a), GETSIGN(b), siglena);
526 }
527 
528 Datum
530 {
531  GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */
532  GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
533  float *penalty = (float *) PG_GETARG_POINTER(2);
534  int siglen = GET_SIGLEN();
535  SignTSVector *origval = (SignTSVector *) DatumGetPointer(origentry->key);
537  BITVECP orig = GETSIGN(origval);
538 
539  *penalty = 0.0;
540 
541  if (ISARRKEY(newval))
542  {
543  BITVECP sign = palloc(siglen);
544 
545  makesign(sign, newval, siglen);
546 
547  if (ISALLTRUE(origval))
548  {
549  int siglenbit = SIGLENBIT(siglen);
550 
551  *penalty =
552  (float) (siglenbit - sizebitvec(sign, siglen)) /
553  (float) (siglenbit + 1);
554  }
555  else
556  *penalty = hemdistsign(sign, orig, siglen);
557 
558  pfree(sign);
559  }
560  else
561  *penalty = hemdist(origval, newval);
562  PG_RETURN_POINTER(penalty);
563 }
564 
565 typedef struct
566 {
567  bool allistrue;
568  BITVECP sign;
569 } CACHESIGN;
570 
571 static void
572 fillcache(CACHESIGN *item, SignTSVector *key, int siglen)
573 {
574  item->allistrue = false;
575  if (ISARRKEY(key))
576  makesign(item->sign, key, siglen);
577  else if (ISALLTRUE(key))
578  item->allistrue = true;
579  else
580  memcpy((void *) item->sign, (void *) GETSIGN(key), siglen);
581 }
582 
583 #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
584 typedef struct
585 {
586  OffsetNumber pos;
587  int32 cost;
588 } SPLITCOST;
589 
590 static int
591 comparecost(const void *va, const void *vb)
592 {
593  const SPLITCOST *a = (const SPLITCOST *) va;
594  const SPLITCOST *b = (const SPLITCOST *) vb;
595 
596  if (a->cost == b->cost)
597  return 0;
598  else
599  return (a->cost > b->cost) ? 1 : -1;
600 }
601 
602 
603 static int
605 {
606  if (a->allistrue)
607  {
608  if (b->allistrue)
609  return 0;
610  else
611  return SIGLENBIT(siglen) - sizebitvec(b->sign, siglen);
612  }
613  else if (b->allistrue)
614  return SIGLENBIT(siglen) - sizebitvec(a->sign, siglen);
615 
616  return hemdistsign(a->sign, b->sign, siglen);
617 }
618 
619 Datum
621 {
624  int siglen = GET_SIGLEN();
625  OffsetNumber k,
626  j;
627  SignTSVector *datum_l,
628  *datum_r;
629  BITVECP union_l,
630  union_r;
631  int32 size_alpha,
632  size_beta;
633  int32 size_waste,
634  waste = -1;
635  int32 nbytes;
636  OffsetNumber seed_1 = 0,
637  seed_2 = 0;
638  OffsetNumber *left,
639  *right;
640  OffsetNumber maxoff;
641  BITVECP ptr;
642  int i;
643  CACHESIGN *cache;
644  char *cache_sign;
645  SPLITCOST *costvector;
646 
647  maxoff = entryvec->n - 2;
648  nbytes = (maxoff + 2) * sizeof(OffsetNumber);
649  v->spl_left = (OffsetNumber *) palloc(nbytes);
650  v->spl_right = (OffsetNumber *) palloc(nbytes);
651 
652  cache = (CACHESIGN *) palloc(sizeof(CACHESIGN) * (maxoff + 2));
653  cache_sign = palloc(siglen * (maxoff + 2));
654 
655  for (j = 0; j < maxoff + 2; j++)
656  cache[j].sign = &cache_sign[siglen * j];
657 
659  siglen);
660 
661  for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
662  {
663  for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
664  {
665  if (k == FirstOffsetNumber)
666  fillcache(&cache[j], GETENTRY(entryvec, j), siglen);
667 
668  size_waste = hemdistcache(&(cache[j]), &(cache[k]), siglen);
669  if (size_waste > waste)
670  {
671  waste = size_waste;
672  seed_1 = k;
673  seed_2 = j;
674  }
675  }
676  }
677 
678  left = v->spl_left;
679  v->spl_nleft = 0;
680  right = v->spl_right;
681  v->spl_nright = 0;
682 
683  if (seed_1 == 0 || seed_2 == 0)
684  {
685  seed_1 = 1;
686  seed_2 = 2;
687  }
688 
689  /* form initial .. */
690  datum_l = gtsvector_alloc(SIGNKEY | (cache[seed_1].allistrue ? ALLISTRUE : 0),
691  siglen, cache[seed_1].sign);
692  datum_r = gtsvector_alloc(SIGNKEY | (cache[seed_2].allistrue ? ALLISTRUE : 0),
693  siglen, cache[seed_2].sign);
694  union_l = GETSIGN(datum_l);
695  union_r = GETSIGN(datum_r);
696  maxoff = OffsetNumberNext(maxoff);
697  fillcache(&cache[maxoff], GETENTRY(entryvec, maxoff), siglen);
698  /* sort before ... */
699  costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
700  for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
701  {
702  costvector[j - 1].pos = j;
703  size_alpha = hemdistcache(&(cache[seed_1]), &(cache[j]), siglen);
704  size_beta = hemdistcache(&(cache[seed_2]), &(cache[j]), siglen);
705  costvector[j - 1].cost = abs(size_alpha - size_beta);
706  }
707  qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
708 
709  for (k = 0; k < maxoff; k++)
710  {
711  j = costvector[k].pos;
712  if (j == seed_1)
713  {
714  *left++ = j;
715  v->spl_nleft++;
716  continue;
717  }
718  else if (j == seed_2)
719  {
720  *right++ = j;
721  v->spl_nright++;
722  continue;
723  }
724 
725  if (ISALLTRUE(datum_l) || cache[j].allistrue)
726  {
727  if (ISALLTRUE(datum_l) && cache[j].allistrue)
728  size_alpha = 0;
729  else
730  size_alpha = SIGLENBIT(siglen) -
731  sizebitvec((cache[j].allistrue) ?
732  GETSIGN(datum_l) :
733  GETSIGN(cache[j].sign),
734  siglen);
735  }
736  else
737  size_alpha = hemdistsign(cache[j].sign, GETSIGN(datum_l), siglen);
738 
739  if (ISALLTRUE(datum_r) || cache[j].allistrue)
740  {
741  if (ISALLTRUE(datum_r) && cache[j].allistrue)
742  size_beta = 0;
743  else
744  size_beta = SIGLENBIT(siglen) -
745  sizebitvec((cache[j].allistrue) ?
746  GETSIGN(datum_r) :
747  GETSIGN(cache[j].sign),
748  siglen);
749  }
750  else
751  size_beta = hemdistsign(cache[j].sign, GETSIGN(datum_r), siglen);
752 
753  if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.1))
754  {
755  if (ISALLTRUE(datum_l) || cache[j].allistrue)
756  {
757  if (!ISALLTRUE(datum_l))
758  memset((void *) GETSIGN(datum_l), 0xff, siglen);
759  }
760  else
761  {
762  ptr = cache[j].sign;
763  LOOPBYTE(siglen)
764  union_l[i] |= ptr[i];
765  }
766  *left++ = j;
767  v->spl_nleft++;
768  }
769  else
770  {
771  if (ISALLTRUE(datum_r) || cache[j].allistrue)
772  {
773  if (!ISALLTRUE(datum_r))
774  memset((void *) GETSIGN(datum_r), 0xff, siglen);
775  }
776  else
777  {
778  ptr = cache[j].sign;
779  LOOPBYTE(siglen)
780  union_r[i] |= ptr[i];
781  }
782  *right++ = j;
783  v->spl_nright++;
784  }
785  }
786 
787  *right = *left = FirstOffsetNumber;
788  v->spl_ldatum = PointerGetDatum(datum_l);
789  v->spl_rdatum = PointerGetDatum(datum_r);
790 
792 }
793 
794 /*
795  * Formerly, gtsvector_consistent was declared in pg_proc.h with arguments
796  * that did not match the documented conventions for GiST support functions.
797  * We fixed that, but we still need a pg_proc entry with the old signature
798  * to support reloading pre-9.6 contrib/tsearch2 opclass declarations.
799  * This compatibility function should go away eventually.
800  */
801 Datum
803 {
804  return gtsvector_consistent(fcinfo);
805 }
806 
807 Datum
809 {
811 
812  init_local_reloptions(relopts, sizeof(GistTsVectorOptions));
813  add_local_int_reloption(relopts, "siglen", "signature length",
815  offsetof(GistTsVectorOptions, siglen));
816 
817  PG_RETURN_VOID();
818 }
#define GETQUERY(x)
Definition: _int.h:157
signed int int32
Definition: c.h:478
#define Max(x, y)
Definition: c.h:982
#define FLEXIBLE_ARRAY_MEMBER
Definition: c.h:382
#define MemSet(start, val, len)
Definition: c.h:1004
#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:1436
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1456
void * palloc(Size size)
Definition: mcxt.c:1210
#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:370
#define HASHVAL(val, siglen)
Definition: tsgistidx.c:53
static int hemdistcache(CACHESIGN *a, CACHESIGN *b, int siglen)
Definition: tsgistidx.c:604
#define LOOPBYTE(siglen)
Definition: tsgistidx.c:44
Datum gtsvector_penalty(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:529
#define ALLISTRUE
Definition: tsgistidx.c:71
#define WISH_F(a, b, c)
Definition: tsgistidx.c:583
static int hemdist(SignTSVector *a, SignTSVector *b)
Definition: tsgistidx.c:508
#define GETBIT(x, i)
Definition: tsgistidx.c:51
static TSTernaryValue checkcondition_arr(void *checkval, QueryOperand *val, ExecPhraseData *data)
Definition: tsgistidx.c:281
static int32 sizebitvec(BITVECP sign, int siglen)
Definition: tsgistidx.c:486
#define ARROUTSTR
Definition: tsgistidx.c:99
static int hemdistsign(BITVECP a, BITVECP b, int siglen)
Definition: tsgistidx.c:492
Datum gtsvector_same(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:425
static SignTSVector * gtsvector_alloc(int flag, int len, BITVECP sign)
Definition: tsgistidx.c:152
#define GETENTRY(vec, pos)
Definition: tsgistidx.c:56
Datum gtsvector_picksplit(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:620
#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:572
#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:591
#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:168
#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:248
Datum gtsvector_consistent(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:330
#define SIGNKEY
Definition: tsgistidx.c:70
static void makesign(BITVECP sign, SignTSVector *a, int siglen)
Definition: tsgistidx.c:140
#define ISSIGNKEY(x)
Definition: tsgistidx.c:74
Datum gtsvector_options(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:808
Datum gtsvector_union(PG_FUNCTION_ARGS)
Definition: tsgistidx.c:398
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:129
#define ARRKEY
Definition: tsgistidx.c:69
static TSTernaryValue checkcondition_bit(void *checkval, QueryOperand *val, ExecPhraseData *data)
Definition: tsgistidx.c:313
#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:802
#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