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