PostgreSQL Source Code git master
Loading...
Searching...
No Matches
trgm_gist.c
Go to the documentation of this file.
1/*
2 * contrib/pg_trgm/trgm_gist.c
3 */
4#include "postgres.h"
5
6#include "access/reloptions.h"
7#include "access/stratnum.h"
8#include "fmgr.h"
9#include "port/pg_bitutils.h"
10#include "trgm.h"
11#include "varatt.h"
12
13/* gist_trgm_ops opclass options */
14typedef struct
15{
16 int32 vl_len_; /* varlena header (do not touch directly!) */
17 int siglen; /* signature length in bytes */
19
20#define GET_SIGLEN() (PG_HAS_OPCLASS_OPTIONS() ? \
21 ((TrgmGistOptions *) PG_GET_OPCLASS_OPTIONS())->siglen : \
22 SIGLEN_DEFAULT)
23
24typedef struct
25{
26 /* most recent inputs to gtrgm_consistent */
29 /* extracted trigrams for query */
31 /* if a regex operator, the extracted graph */
33
34 /*
35 * The "query" and "trigrams" are stored in the same palloc block as this
36 * cache struct, at MAXALIGN'ed offsets. The graph however isn't.
37 */
39
40#define GETENTRY(vec,pos) ((TRGM *) DatumGetPointer((vec)->vector[(pos)].key))
41
42
54
55
58{
61 errmsg("cannot accept a value of type %s", "gtrgm")));
62
63 PG_RETURN_VOID(); /* keep compiler quiet */
64}
65
68{
71 errmsg("cannot display a value of type %s", "gtrgm")));
72
73 PG_RETURN_VOID(); /* keep compiler quiet */
74}
75
76static TRGM *
78{
79 int flag = SIGNKEY | (isalltrue ? ALLISTRUE : 0);
80 int size = CALCGTSIZE(flag, siglen);
81 TRGM *res = palloc(size);
82
83 SET_VARSIZE(res, size);
84 res->flag = flag;
85
86 if (!isalltrue)
87 {
88 if (sign)
89 memcpy(GETSIGN(res), sign, siglen);
90 else
91 memset(GETSIGN(res), 0, siglen);
92 }
93
94 return res;
95}
96
97static void
98makesign(BITVECP sign, TRGM *a, int siglen)
99{
100 int32 k,
101 len = ARRNELEM(a);
102 trgm *ptr = GETARR(a);
103 int32 tmp = 0;
104
105 MemSet(sign, 0, siglen);
106 SETBIT(sign, SIGLENBIT(siglen)); /* set last unused bit */
107 for (k = 0; k < len; k++)
108 {
109 CPTRGM(&tmp, ptr + k);
110 HASH(sign, tmp, siglen);
111 }
112}
113
114Datum
116{
117 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
118 int siglen = GET_SIGLEN();
119 GISTENTRY *retval = entry;
120
121 if (entry->leafkey)
122 { /* trgm */
123 TRGM *res;
124 text *val = DatumGetTextPP(entry->key);
125
127 retval = palloc_object(GISTENTRY);
128 gistentryinit(*retval, PointerGetDatum(res),
129 entry->rel, entry->page,
130 entry->offset, false);
131 }
132 else if (ISSIGNKEY(DatumGetPointer(entry->key)) &&
133 !ISALLTRUE(DatumGetPointer(entry->key)))
134 {
135 int32 i;
136 TRGM *res;
138
139 LOOPBYTE(siglen)
140 {
141 if ((sign[i] & 0xff) != 0xff)
142 PG_RETURN_POINTER(retval);
143 }
144
145 res = gtrgm_alloc(true, siglen, sign);
146 retval = palloc_object(GISTENTRY);
147 gistentryinit(*retval, PointerGetDatum(res),
148 entry->rel, entry->page,
149 entry->offset, false);
150 }
151 PG_RETURN_POINTER(retval);
152}
153
154Datum
156{
157 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
158 GISTENTRY *retval;
159 text *key;
160
161 key = DatumGetTextPP(entry->key);
162
163 if (key != (text *) DatumGetPointer(entry->key))
164 {
165 /* need to pass back the decompressed item */
166 retval = palloc_object(GISTENTRY);
167 gistentryinit(*retval, PointerGetDatum(key),
168 entry->rel, entry->page, entry->offset, entry->leafkey);
169 PG_RETURN_POINTER(retval);
170 }
171 else
172 {
173 /* we can return the entry as-is */
174 PG_RETURN_POINTER(entry);
175 }
176}
177
178static int32
180{
181 int32 count = 0;
182 int32 k,
183 len = ARRNELEM(qtrg);
184 trgm *ptr = GETARR(qtrg);
185 int32 tmp = 0;
186
187 for (k = 0; k < len; k++)
188 {
189 CPTRGM(&tmp, ptr + k);
190 count += GETBIT(sign, HASHVAL(tmp, siglen));
191 }
192
193 return count;
194}
195
196Datum
198{
199 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
200 text *query = PG_GETARG_TEXT_P(1);
202#ifdef NOT_USED
203 Oid subtype = PG_GETARG_OID(3);
204#endif
205 bool *recheck = (bool *) PG_GETARG_POINTER(4);
206 int siglen = GET_SIGLEN();
207 TRGM *key = (TRGM *) DatumGetPointer(entry->key);
208 TRGM *qtrg;
209 bool res;
210 Size querysize = VARSIZE(query);
212 double nlimit;
213
214 /*
215 * We keep the extracted trigrams in cache, because trigram extraction is
216 * relatively CPU-expensive. When trying to reuse a cached value, check
217 * strategy number not just query itself, because trigram extraction
218 * depends on strategy.
219 *
220 * The cached structure is a single palloc chunk containing the
221 * gtrgm_consistent_cache header, then the input query (4-byte length
222 * word, uncompressed, starting at a MAXALIGN boundary), then the TRGM
223 * value (also starting at a MAXALIGN boundary). However we don't try to
224 * include the regex graph (if any) in that struct. (XXX currently, this
225 * approach can leak regex graphs across index rescans. Not clear if
226 * that's worth fixing.)
227 */
228 cache = (gtrgm_consistent_cache *) fcinfo->flinfo->fn_extra;
229 if (cache == NULL ||
230 cache->strategy != strategy ||
231 VARSIZE(cache->query) != querysize ||
232 memcmp(cache->query, query, querysize) != 0)
233 {
235 TrgmPackedGraph *graph = NULL;
237
238 switch (strategy)
239 {
244 qtrg = generate_trgm(VARDATA(query),
246 break;
248#ifndef IGNORECASE
249 elog(ERROR, "cannot handle ~~* with case-sensitive trigrams");
250#endif
251 /* FALL THRU */
255 break;
257#ifndef IGNORECASE
258 elog(ERROR, "cannot handle ~* with case-sensitive trigrams");
259#endif
260 /* FALL THRU */
263 &graph, fcinfo->flinfo->fn_mcxt);
264 /* just in case an empty array is returned ... */
265 if (qtrg && ARRNELEM(qtrg) <= 0)
266 {
267 pfree(qtrg);
268 qtrg = NULL;
269 }
270 break;
271 default:
272 elog(ERROR, "unrecognized strategy number: %d", strategy);
273 qtrg = NULL; /* keep compiler quiet */
274 break;
275 }
276
277 qtrgsize = qtrg ? VARSIZE(qtrg) : 0;
278
280 MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
283 qtrgsize);
284
285 newcache->strategy = strategy;
286 newcache->query = (text *)
287 ((char *) newcache + MAXALIGN(sizeof(gtrgm_consistent_cache)));
288 memcpy(newcache->query, query, querysize);
289 if (qtrg)
290 {
291 newcache->trigrams = (TRGM *)
292 ((char *) newcache->query + MAXALIGN(querysize));
293 memcpy((char *) newcache->trigrams, qtrg, qtrgsize);
294 /* release qtrg in case it was made in fn_mcxt */
295 pfree(qtrg);
296 }
297 else
298 newcache->trigrams = NULL;
299 newcache->graph = graph;
300
301 if (cache)
302 pfree(cache);
303 fcinfo->flinfo->fn_extra = newcache;
304 cache = newcache;
305 }
306
307 qtrg = cache->trigrams;
308
309 switch (strategy)
310 {
314
315 /*
316 * Similarity search is exact. (Strict) word similarity search is
317 * inexact
318 */
319 *recheck = (strategy != SimilarityStrategyNumber);
320
322
323 if (GIST_LEAF(entry))
324 { /* all leafs contains orig trgm */
325 double tmpsml = cnt_sml(qtrg, key, *recheck);
326
327 res = (tmpsml >= nlimit);
328 }
329 else if (ISALLTRUE(key))
330 { /* non-leaf contains signature */
331 res = true;
332 }
333 else
334 { /* non-leaf contains signature */
335 int32 count = cnt_sml_sign_common(qtrg, GETSIGN(key), siglen);
337
338 if (len == 0)
339 res = false;
340 else
341 res = (((((float8) count) / ((float8) len))) >= nlimit);
342 }
343 break;
345#ifndef IGNORECASE
346 elog(ERROR, "cannot handle ~~* with case-sensitive trigrams");
347#endif
348 /* FALL THRU */
351 /* Wildcard and equal search are inexact */
352 *recheck = true;
353
354 /*
355 * Check if all the extracted trigrams can be present in child
356 * nodes.
357 */
358 if (GIST_LEAF(entry))
359 { /* all leafs contains orig trgm */
360 res = trgm_contained_by(qtrg, key);
361 }
362 else if (ISALLTRUE(key))
363 { /* non-leaf contains signature */
364 res = true;
365 }
366 else
367 { /* non-leaf contains signature */
368 int32 k,
369 tmp = 0,
370 len = ARRNELEM(qtrg);
371 trgm *ptr = GETARR(qtrg);
372 BITVECP sign = GETSIGN(key);
373
374 res = true;
375 for (k = 0; k < len; k++)
376 {
377 CPTRGM(&tmp, ptr + k);
378 if (!GETBIT(sign, HASHVAL(tmp, siglen)))
379 {
380 res = false;
381 break;
382 }
383 }
384 }
385 break;
387#ifndef IGNORECASE
388 elog(ERROR, "cannot handle ~* with case-sensitive trigrams");
389#endif
390 /* FALL THRU */
392 /* Regexp search is inexact */
393 *recheck = true;
394
395 /* Check regex match as much as we can with available info */
396 if (qtrg)
397 {
398 if (GIST_LEAF(entry))
399 { /* all leafs contains orig trgm */
400 bool *check;
401
402 check = trgm_presence_map(qtrg, key);
403 res = trigramsMatchGraph(cache->graph, check);
404 pfree(check);
405 }
406 else if (ISALLTRUE(key))
407 { /* non-leaf contains signature */
408 res = true;
409 }
410 else
411 { /* non-leaf contains signature */
412 int32 k,
413 tmp = 0,
414 len = ARRNELEM(qtrg);
415 trgm *ptr = GETARR(qtrg);
416 BITVECP sign = GETSIGN(key);
417 bool *check;
418
419 /*
420 * GETBIT() tests may give false positives, due to limited
421 * size of the sign array. But since trigramsMatchGraph()
422 * implements a monotone boolean function, false positives
423 * in the check array can't lead to false negative answer.
424 * So we can apply trigramsMatchGraph despite uncertainty,
425 * and that usefully improves the quality of the search.
426 */
427 check = (bool *) palloc(len * sizeof(bool));
428 for (k = 0; k < len; k++)
429 {
430 CPTRGM(&tmp, ptr + k);
431 check[k] = GETBIT(sign, HASHVAL(tmp, siglen));
432 }
433 res = trigramsMatchGraph(cache->graph, check);
434 pfree(check);
435 }
436 }
437 else
438 {
439 /* trigram-free query must be rechecked everywhere */
440 res = true;
441 }
442 break;
443 default:
444 elog(ERROR, "unrecognized strategy number: %d", strategy);
445 res = false; /* keep compiler quiet */
446 break;
447 }
448
449 PG_RETURN_BOOL(res);
450}
451
452Datum
454{
455 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
456 text *query = PG_GETARG_TEXT_P(1);
458#ifdef NOT_USED
459 Oid subtype = PG_GETARG_OID(3);
460#endif
461 bool *recheck = (bool *) PG_GETARG_POINTER(4);
462 int siglen = GET_SIGLEN();
463 TRGM *key = (TRGM *) DatumGetPointer(entry->key);
464 TRGM *qtrg;
465 float8 res;
466 Size querysize = VARSIZE(query);
467 char *cache = (char *) fcinfo->flinfo->fn_extra;
468
469 /*
470 * Cache the generated trigrams across multiple calls with the same query.
471 */
472 if (cache == NULL ||
473 VARSIZE(cache) != querysize ||
474 memcmp(cache, query, querysize) != 0)
475 {
476 char *newcache;
477
479
480 newcache = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
482 VARSIZE(qtrg));
483
484 memcpy(newcache, query, querysize);
486
487 if (cache)
488 pfree(cache);
489 fcinfo->flinfo->fn_extra = newcache;
490 cache = newcache;
491 }
492
493 qtrg = (TRGM *) (cache + MAXALIGN(querysize));
494
495 switch (strategy)
496 {
500 /* Only plain trigram distance is exact */
501 *recheck = (strategy != DistanceStrategyNumber);
502 if (GIST_LEAF(entry))
503 { /* all leafs contains orig trgm */
504
505 /*
506 * Prevent gcc optimizing the sml variable using volatile
507 * keyword. Otherwise res can differ from the
508 * word_similarity_dist_op() function.
509 */
510 float4 volatile sml = cnt_sml(qtrg, key, *recheck);
511
512 res = 1.0 - sml;
513 }
514 else if (ISALLTRUE(key))
515 { /* all leafs contains orig trgm */
516 res = 0.0;
517 }
518 else
519 { /* non-leaf contains signature */
520 int32 count = cnt_sml_sign_common(qtrg, GETSIGN(key), siglen);
522
523 res = (len == 0) ? -1.0 : 1.0 - ((float8) count) / ((float8) len);
524 }
525 break;
526 default:
527 elog(ERROR, "unrecognized strategy number: %d", strategy);
528 res = 0; /* keep compiler quiet */
529 break;
530 }
531
532 PG_RETURN_FLOAT8(res);
533}
534
535static int32
537{
538 int32 i;
539
540 if (ISSIGNKEY(add))
541 {
543
544 if (ISALLTRUE(add))
545 return 1;
546
547 LOOPBYTE(siglen)
548 sbase[i] |= sadd[i];
549 }
550 else
551 {
552 trgm *ptr = GETARR(add);
553 int32 tmp = 0;
554
555 for (i = 0; i < ARRNELEM(add); i++)
556 {
557 CPTRGM(&tmp, ptr + i);
558 HASH(sbase, tmp, siglen);
559 }
560 }
561 return 0;
562}
563
564
565Datum
567{
569 int32 len = entryvec->n;
570 int *size = (int *) PG_GETARG_POINTER(1);
571 int siglen = GET_SIGLEN();
572 int32 i;
573 TRGM *result = gtrgm_alloc(false, siglen, NULL);
574 BITVECP base = GETSIGN(result);
575
576 for (i = 0; i < len; i++)
577 {
578 if (unionkey(base, GETENTRY(entryvec, i), siglen))
579 {
580 result->flag = ALLISTRUE;
581 SET_VARSIZE(result, CALCGTSIZE(ALLISTRUE, siglen));
582 break;
583 }
584 }
585
586 *size = VARSIZE(result);
587
588 PG_RETURN_POINTER(result);
589}
590
591Datum
593{
594 TRGM *a = (TRGM *) PG_GETARG_POINTER(0);
595 TRGM *b = (TRGM *) PG_GETARG_POINTER(1);
596 bool *result = (bool *) PG_GETARG_POINTER(2);
597 int siglen = GET_SIGLEN();
598
599 if (ISSIGNKEY(a))
600 { /* then b also ISSIGNKEY */
601 if (ISALLTRUE(a) && ISALLTRUE(b))
602 *result = true;
603 else if (ISALLTRUE(a))
604 *result = false;
605 else if (ISALLTRUE(b))
606 *result = false;
607 else
608 {
609 int32 i;
610 BITVECP sa = GETSIGN(a),
611 sb = GETSIGN(b);
612
613 *result = true;
614 LOOPBYTE(siglen)
615 {
616 if (sa[i] != sb[i])
617 {
618 *result = false;
619 break;
620 }
621 }
622 }
623 }
624 else
625 { /* a and b ISARRKEY */
626 int32 lena = ARRNELEM(a),
627 lenb = ARRNELEM(b);
628
629 if (lena != lenb)
630 *result = false;
631 else
632 {
633 trgm *ptra = GETARR(a),
634 *ptrb = GETARR(b);
635 int32 i;
636
637 *result = true;
638 for (i = 0; i < lena; i++)
639 if (CMPTRGM(ptra + i, ptrb + i))
640 {
641 *result = false;
642 break;
643 }
644 }
645 }
646
647 PG_RETURN_POINTER(result);
648}
649
650static int32
652{
653 return pg_popcount(sign, siglen);
654}
655
656static int
658{
659 int i,
660 diff,
661 dist = 0;
662
663 LOOPBYTE(siglen)
664 {
665 diff = (unsigned char) (a[i] ^ b[i]);
666 /* Using the popcount functions here isn't likely to win */
668 }
669 return dist;
670}
671
672static int
673hemdist(TRGM *a, TRGM *b, int siglen)
674{
675 if (ISALLTRUE(a))
676 {
677 if (ISALLTRUE(b))
678 return 0;
679 else
680 return SIGLENBIT(siglen) - sizebitvec(GETSIGN(b), siglen);
681 }
682 else if (ISALLTRUE(b))
683 return SIGLENBIT(siglen) - sizebitvec(GETSIGN(a), siglen);
684
685 return hemdistsign(GETSIGN(a), GETSIGN(b), siglen);
686}
687
688Datum
690{
691 GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */
693 float *penalty = (float *) PG_GETARG_POINTER(2);
694 int siglen = GET_SIGLEN();
698
699 *penalty = 0.0;
700
701 if (ISARRKEY(newval))
702 {
703 char *cache = (char *) fcinfo->flinfo->fn_extra;
707
708 if (cache != NULL)
709 cachedVal = (TRGM *) (cache + MAXALIGN(siglen));
710
711 /*
712 * Cache the sign data across multiple calls with the same newval.
713 */
714 if (cache == NULL ||
717 {
718 char *newcache;
719
720 newcache = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
721 MAXALIGN(siglen) +
722 newvalsize);
723
724 makesign((BITVECP) newcache, newval, siglen);
725
726 cachedVal = (TRGM *) (newcache + MAXALIGN(siglen));
728
729 if (cache)
730 pfree(cache);
731 fcinfo->flinfo->fn_extra = newcache;
732 cache = newcache;
733 }
734
735 sign = (BITVECP) cache;
736
737 if (ISALLTRUE(origval))
738 *penalty = ((float) (SIGLENBIT(siglen) - sizebitvec(sign, siglen))) / (float) (SIGLENBIT(siglen) + 1);
739 else
740 *penalty = hemdistsign(sign, orig, siglen);
741 }
742 else
743 *penalty = hemdist(origval, newval, siglen);
744 PG_RETURN_POINTER(penalty);
745}
746
747typedef struct
748{
751} CACHESIGN;
752
753static void
754fillcache(CACHESIGN *item, TRGM *key, BITVECP sign, int siglen)
755{
756 item->allistrue = false;
757 item->sign = sign;
758 if (ISARRKEY(key))
759 makesign(item->sign, key, siglen);
760 else if (ISALLTRUE(key))
761 item->allistrue = true;
762 else
763 memcpy(item->sign, GETSIGN(key), siglen);
764}
765
766#define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
767typedef struct
768{
769 OffsetNumber pos;
770 int32 cost;
771} SPLITCOST;
772
773static int
774comparecost(const void *a, const void *b)
775{
776 if (((const SPLITCOST *) a)->cost == ((const SPLITCOST *) b)->cost)
777 return 0;
778 else
779 return (((const SPLITCOST *) a)->cost > ((const SPLITCOST *) b)->cost) ? 1 : -1;
780}
781
782
783static int
785{
786 if (a->allistrue)
787 {
788 if (b->allistrue)
789 return 0;
790 else
791 return SIGLENBIT(siglen) - sizebitvec(b->sign, siglen);
792 }
793 else if (b->allistrue)
794 return SIGLENBIT(siglen) - sizebitvec(a->sign, siglen);
795
796 return hemdistsign(a->sign, b->sign, siglen);
797}
798
799Datum
801{
803 OffsetNumber maxoff = entryvec->n - 1;
805 int siglen = GET_SIGLEN();
806 OffsetNumber k,
807 j;
808 TRGM *datum_l,
809 *datum_r;
811 union_r;
813 size_beta;
815 waste = -1;
816 int32 nbytes;
818 seed_2 = 0;
819 OffsetNumber *left,
820 *right;
821 BITVECP ptr;
822 int i;
823 CACHESIGN *cache;
824 char *cache_sign;
826
827 /* cache the sign data for each existing item */
828 cache = palloc_array(CACHESIGN, maxoff + 1);
829 cache_sign = palloc(siglen * (maxoff + 1));
830
831 for (k = FirstOffsetNumber; k <= maxoff; k = OffsetNumberNext(k))
832 fillcache(&cache[k], GETENTRY(entryvec, k), &cache_sign[siglen * k],
833 siglen);
834
835 /* now find the two furthest-apart items */
836 for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
837 {
838 for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
839 {
840 size_waste = hemdistcache(&(cache[j]), &(cache[k]), siglen);
841 if (size_waste > waste)
842 {
843 waste = size_waste;
844 seed_1 = k;
845 seed_2 = j;
846 }
847 }
848 }
849
850 /* just in case we didn't make a selection ... */
851 if (seed_1 == 0 || seed_2 == 0)
852 {
853 seed_1 = 1;
854 seed_2 = 2;
855 }
856
857 /* initialize the result vectors */
858 nbytes = maxoff * sizeof(OffsetNumber);
859 v->spl_left = left = (OffsetNumber *) palloc(nbytes);
860 v->spl_right = right = (OffsetNumber *) palloc(nbytes);
861 v->spl_nleft = 0;
862 v->spl_nright = 0;
863
864 /* form initial .. */
865 datum_l = gtrgm_alloc(cache[seed_1].allistrue, siglen, cache[seed_1].sign);
866 datum_r = gtrgm_alloc(cache[seed_2].allistrue, siglen, cache[seed_2].sign);
867
870
871 /* sort before ... */
873 for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
874 {
875 costvector[j - 1].pos = j;
876 size_alpha = hemdistcache(&(cache[seed_1]), &(cache[j]), siglen);
877 size_beta = hemdistcache(&(cache[seed_2]), &(cache[j]), siglen);
878 costvector[j - 1].cost = abs(size_alpha - size_beta);
879 }
880 qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
881
882 for (k = 0; k < maxoff; k++)
883 {
884 j = costvector[k].pos;
885 if (j == seed_1)
886 {
887 *left++ = j;
888 v->spl_nleft++;
889 continue;
890 }
891 else if (j == seed_2)
892 {
893 *right++ = j;
894 v->spl_nright++;
895 continue;
896 }
897
898 if (ISALLTRUE(datum_l) || cache[j].allistrue)
899 {
900 if (ISALLTRUE(datum_l) && cache[j].allistrue)
901 size_alpha = 0;
902 else
903 size_alpha = SIGLENBIT(siglen) -
904 sizebitvec((cache[j].allistrue) ? GETSIGN(datum_l) :
905 GETSIGN(cache[j].sign),
906 siglen);
907 }
908 else
909 size_alpha = hemdistsign(cache[j].sign, GETSIGN(datum_l), siglen);
910
911 if (ISALLTRUE(datum_r) || cache[j].allistrue)
912 {
913 if (ISALLTRUE(datum_r) && cache[j].allistrue)
914 size_beta = 0;
915 else
916 size_beta = SIGLENBIT(siglen) -
917 sizebitvec((cache[j].allistrue) ? GETSIGN(datum_r) :
918 GETSIGN(cache[j].sign),
919 siglen);
920 }
921 else
922 size_beta = hemdistsign(cache[j].sign, GETSIGN(datum_r), siglen);
923
924 if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.1))
925 {
926 if (ISALLTRUE(datum_l) || cache[j].allistrue)
927 {
928 if (!ISALLTRUE(datum_l))
929 memset(GETSIGN(datum_l), 0xff, siglen);
930 }
931 else
932 {
933 ptr = cache[j].sign;
934 LOOPBYTE(siglen)
935 union_l[i] |= ptr[i];
936 }
937 *left++ = j;
938 v->spl_nleft++;
939 }
940 else
941 {
942 if (ISALLTRUE(datum_r) || cache[j].allistrue)
943 {
944 if (!ISALLTRUE(datum_r))
945 memset(GETSIGN(datum_r), 0xff, siglen);
946 }
947 else
948 {
949 ptr = cache[j].sign;
950 LOOPBYTE(siglen)
951 union_r[i] |= ptr[i];
952 }
953 *right++ = j;
954 v->spl_nright++;
955 }
956 }
957
960
962}
963
964Datum
#define GETBIT(x, i)
Definition blutils.c:30
#define SETBIT(x, i)
Definition blutils.c:29
#define MAXALIGN(LEN)
Definition c.h:826
#define VARHDRSZ
Definition c.h:711
double float8
Definition c.h:644
int32_t int32
Definition c.h:542
float float4
Definition c.h:643
#define MemSet(start, val, len)
Definition c.h:1013
size_t Size
Definition c.h:619
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
#define palloc_object(type)
Definition fe_memutils.h:74
#define palloc_array(type, count)
Definition fe_memutils.h:76
#define PG_RETURN_VOID()
Definition fmgr.h:350
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_RETURN_FLOAT8(x)
Definition fmgr.h:369
#define DatumGetTextPP(X)
Definition fmgr.h:293
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
#define PG_FUNCTION_INFO_V1(funcname)
Definition fmgr.h:417
#define PG_GETARG_UINT16(n)
Definition fmgr.h:272
#define PG_RETURN_POINTER(x)
Definition fmgr.h:363
#define PG_GET_COLLATION()
Definition fmgr.h:198
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
#define PG_GETARG_TEXT_P(n)
Definition fmgr.h:337
#define GIST_LEAF(entry)
Definition gist.h:171
#define gistentryinit(e, k, r, pg, o, l)
Definition gist.h:245
#define newval
#define HASHVAL(val, siglen)
Definition hstore_gist.c:45
#define LOOPBYTE(siglen)
Definition hstore_gist.c:33
#define ALLISTRUE
Definition hstore_gist.c:55
#define CALCGTSIZE(flag, siglen)
Definition hstore_gist.c:60
#define ISALLTRUE(x)
Definition hstore_gist.c:57
#define SIGLEN_MAX
Definition hstore_gist.c:24
#define SIGLEN_DEFAULT
Definition hstore_gist.c:23
char * BITVECP
Definition hstore_gist.c:31
#define SIGLENBIT(siglen)
Definition hstore_gist.c:25
#define GETSIGN(x)
Definition hstore_gist.c:62
#define HASH(sign, val, siglen)
Definition hstore_gist.c:46
long val
Definition informix.c:689
char sign
Definition informix.c:693
int b
Definition isn.c:74
int a
Definition isn.c:73
int j
Definition isn.c:78
int i
Definition isn.c:77
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1232
void pfree(void *pointer)
Definition mcxt.c:1616
void * palloc(Size size)
Definition mcxt.c:1387
#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:80
static uint64 pg_popcount(const char *buf, int bytes)
const void size_t len
#define qsort(a, b, c, d)
Definition port.h:495
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
uint64_t Datum
Definition postgres.h:70
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:342
unsigned int Oid
static int fb(int x)
void init_local_reloptions(local_relopts *relopts, Size relopt_struct_size)
Definition reloptions.c:782
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)
uint16 StrategyNumber
Definition stratnum.h:22
BITVECP sign
Definition trgm_gist.c:750
bool allistrue
Definition trgm_gist.c:749
OffsetNumber offset
Definition gist.h:164
Datum key
Definition gist.h:161
Page page
Definition gist.h:163
Relation rel
Definition gist.h:162
bool leafkey
Definition gist.h:165
int spl_nleft
Definition gist.h:144
OffsetNumber * spl_right
Definition gist.h:148
Datum spl_ldatum
Definition gist.h:145
Datum spl_rdatum
Definition gist.h:150
int spl_nright
Definition gist.h:149
OffsetNumber * spl_left
Definition gist.h:143
Definition trgm.h:58
uint8 flag
Definition trgm.h:60
StrategyNumber strategy
Definition trgm_gist.c:27
TrgmPackedGraph * graph
Definition trgm_gist.c:32
Definition c.h:706
char * flag(int b)
Definition test-ctype.c:33
#define RegExpICaseStrategyNumber
Definition trgm.h:34
#define WordSimilarityStrategyNumber
Definition trgm.h:35
TRGM * generate_trgm(char *str, int slen)
Definition trgm_op.c:406
#define DistanceStrategyNumber
Definition trgm.h:30
#define StrictWordSimilarityStrategyNumber
Definition trgm.h:37
#define StrictWordDistanceStrategyNumber
Definition trgm.h:38
int(* CMPTRGM)(const void *a, const void *b)
Definition trgm_op.c:49
#define ISARRKEY(x)
Definition trgm.h:91
bool * trgm_presence_map(TRGM *query, TRGM *key)
Definition trgm_op.c:1128
#define ARRNELEM(x)
Definition trgm.h:98
double index_strategy_get_limit(StrategyNumber strategy)
Definition trgm_op.c:182
TRGM * createTrgmNFA(text *text_re, Oid collation, TrgmPackedGraph **graph, MemoryContext rcontext)
#define SimilarityStrategyNumber
Definition trgm.h:29
bool trigramsMatchGraph(TrgmPackedGraph *graph, bool *check)
bool trgm_contained_by(TRGM *trg1, TRGM *trg2)
Definition trgm_op.c:1089
#define SIGNKEY
Definition trgm.h:88
#define ISSIGNKEY(x)
Definition trgm.h:92
char trgm[3]
Definition trgm.h:41
#define CPTRGM(a, b)
Definition trgm.h:43
#define ILikeStrategyNumber
Definition trgm.h:32
TRGM * generate_wildcard_trgm(const char *str, int slen)
Definition trgm_op.c:916
float4 cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact)
Definition trgm_op.c:1041
#define LikeStrategyNumber
Definition trgm.h:31
#define GETARR(x)
Definition trgm.h:97
#define EqualStrategyNumber
Definition trgm.h:39
#define RegExpStrategyNumber
Definition trgm.h:33
#define WordDistanceStrategyNumber
Definition trgm.h:36
Datum gtrgm_out(PG_FUNCTION_ARGS)
Definition trgm_gist.c:67
static int hemdistcache(CACHESIGN *a, CACHESIGN *b, int siglen)
Definition trgm_gist.c:784
static void fillcache(CACHESIGN *item, TRGM *key, BITVECP sign, int siglen)
Definition trgm_gist.c:754
Datum gtrgm_same(PG_FUNCTION_ARGS)
Definition trgm_gist.c:592
#define WISH_F(a, b, c)
Definition trgm_gist.c:766
static int32 unionkey(BITVECP sbase, TRGM *add, int siglen)
Definition trgm_gist.c:536
Datum gtrgm_distance(PG_FUNCTION_ARGS)
Definition trgm_gist.c:453
static int32 sizebitvec(BITVECP sign, int siglen)
Definition trgm_gist.c:651
Datum gtrgm_in(PG_FUNCTION_ARGS)
Definition trgm_gist.c:57
Datum gtrgm_options(PG_FUNCTION_ARGS)
Definition trgm_gist.c:965
static int hemdistsign(BITVECP a, BITVECP b, int siglen)
Definition trgm_gist.c:657
#define GETENTRY(vec, pos)
Definition trgm_gist.c:40
Datum gtrgm_compress(PG_FUNCTION_ARGS)
Definition trgm_gist.c:115
Datum gtrgm_picksplit(PG_FUNCTION_ARGS)
Definition trgm_gist.c:800
Datum gtrgm_decompress(PG_FUNCTION_ARGS)
Definition trgm_gist.c:155
static TRGM * gtrgm_alloc(bool isalltrue, int siglen, BITVECP sign)
Definition trgm_gist.c:77
Datum gtrgm_union(PG_FUNCTION_ARGS)
Definition trgm_gist.c:566
Datum gtrgm_penalty(PG_FUNCTION_ARGS)
Definition trgm_gist.c:689
#define GET_SIGLEN()
Definition trgm_gist.c:20
static void makesign(BITVECP sign, TRGM *a, int siglen)
Definition trgm_gist.c:98
Datum gtrgm_consistent(PG_FUNCTION_ARGS)
Definition trgm_gist.c:197
static int32 cnt_sml_sign_common(TRGM *qtrg, BITVECP sign, int siglen)
Definition trgm_gist.c:179
static int hemdist(TRGM *a, TRGM *b, int siglen)
Definition trgm_gist.c:673
static int comparecost(const void *a, const void *b)
Definition trgm_gist.c:774
char * BITVECP
Definition tsgistidx.c:43
static Size VARSIZE_ANY_EXHDR(const void *PTR)
Definition varatt.h:472
static Size VARSIZE(const void *PTR)
Definition varatt.h:298
static char * VARDATA(const void *PTR)
Definition varatt.h:305
static char * VARDATA_ANY(const void *PTR)
Definition varatt.h:486
static void SET_VARSIZE(void *PTR, Size len)
Definition varatt.h:432