PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
trgm_gin.c File Reference
#include "postgres.h"
#include "trgm.h"
#include "access/gin.h"
#include "access/stratnum.h"
#include "fmgr.h"
Include dependency graph for trgm_gin.c:

Go to the source code of this file.

Functions

 PG_FUNCTION_INFO_V1 (gin_extract_trgm)
 
 PG_FUNCTION_INFO_V1 (gin_extract_value_trgm)
 
 PG_FUNCTION_INFO_V1 (gin_extract_query_trgm)
 
 PG_FUNCTION_INFO_V1 (gin_trgm_consistent)
 
 PG_FUNCTION_INFO_V1 (gin_trgm_triconsistent)
 
Datum gin_extract_trgm (PG_FUNCTION_ARGS)
 
Datum gin_extract_value_trgm (PG_FUNCTION_ARGS)
 
Datum gin_extract_query_trgm (PG_FUNCTION_ARGS)
 
Datum gin_trgm_consistent (PG_FUNCTION_ARGS)
 
Datum gin_trgm_triconsistent (PG_FUNCTION_ARGS)
 

Function Documentation

Datum gin_extract_query_trgm ( PG_FUNCTION_ARGS  )

Definition at line 71 of file trgm_gin.c.

References ARRNELEM, createTrgmNFA(), CurrentMemoryContext, elog, ERROR, generate_trgm(), generate_wildcard_trgm(), GETARR, GIN_SEARCH_MODE_ALL, i, ILikeStrategyNumber, Int32GetDatum, LikeStrategyNumber, NULL, palloc(), PG_GET_COLLATION, PG_GETARG_POINTER, PG_GETARG_TEXT_P, PG_GETARG_UINT16, PG_RETURN_POINTER, RegExpICaseStrategyNumber, RegExpStrategyNumber, SimilarityStrategyNumber, trgm2int(), val, VARDATA, VARHDRSZ, VARSIZE, and WordSimilarityStrategyNumber.

Referenced by gin_extract_trgm().

72 {
73  text *val = (text *) PG_GETARG_TEXT_P(0);
74  int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
75  StrategyNumber strategy = PG_GETARG_UINT16(2);
76 
77  /* bool **pmatch = (bool **) PG_GETARG_POINTER(3); */
78  Pointer **extra_data = (Pointer **) PG_GETARG_POINTER(4);
79 
80  /* bool **nullFlags = (bool **) PG_GETARG_POINTER(5); */
81  int32 *searchMode = (int32 *) PG_GETARG_POINTER(6);
82  Datum *entries = NULL;
83  TRGM *trg;
84  int32 trglen;
85  trgm *ptr;
86  TrgmPackedGraph *graph;
87  int32 i;
88 
89  switch (strategy)
90  {
93  trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
94  break;
96 #ifndef IGNORECASE
97  elog(ERROR, "cannot handle ~~* with case-sensitive trigrams");
98 #endif
99  /* FALL THRU */
100  case LikeStrategyNumber:
101 
102  /*
103  * For wildcard search we extract all the trigrams that every
104  * potentially-matching string must include.
105  */
106  trg = generate_wildcard_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
107  break;
109 #ifndef IGNORECASE
110  elog(ERROR, "cannot handle ~* with case-sensitive trigrams");
111 #endif
112  /* FALL THRU */
114  trg = createTrgmNFA(val, PG_GET_COLLATION(),
115  &graph, CurrentMemoryContext);
116  if (trg && ARRNELEM(trg) > 0)
117  {
118  /*
119  * Successful regex processing: store NFA-like graph as
120  * extra_data. GIN API requires an array of nentries
121  * Pointers, but we just put the same value in each element.
122  */
123  trglen = ARRNELEM(trg);
124  *extra_data = (Pointer *) palloc(sizeof(Pointer) * trglen);
125  for (i = 0; i < trglen; i++)
126  (*extra_data)[i] = (Pointer) graph;
127  }
128  else
129  {
130  /* No result: have to do full index scan. */
131  *nentries = 0;
132  *searchMode = GIN_SEARCH_MODE_ALL;
133  PG_RETURN_POINTER(entries);
134  }
135  break;
136  default:
137  elog(ERROR, "unrecognized strategy number: %d", strategy);
138  trg = NULL; /* keep compiler quiet */
139  break;
140  }
141 
142  trglen = ARRNELEM(trg);
143  *nentries = trglen;
144 
145  if (trglen > 0)
146  {
147  entries = (Datum *) palloc(sizeof(Datum) * trglen);
148  ptr = GETARR(trg);
149  for (i = 0; i < trglen; i++)
150  {
151  int32 item = trgm2int(ptr);
152 
153  entries[i] = Int32GetDatum(item);
154  ptr++;
155  }
156  }
157 
158  /*
159  * If no trigram was extracted then we have to scan all the index.
160  */
161  if (trglen == 0)
162  *searchMode = GIN_SEARCH_MODE_ALL;
163 
164  PG_RETURN_POINTER(entries);
165 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
#define VARDATA(PTR)
Definition: postgres.h:305
#define RegExpStrategyNumber
Definition: trgm.h:33
TRGM * generate_wildcard_trgm(const char *str, int slen)
Definition: trgm_op.c:796
#define SimilarityStrategyNumber
Definition: trgm.h:29
#define VARSIZE(PTR)
Definition: postgres.h:306
#define VARHDRSZ
Definition: c.h:440
TRGM * createTrgmNFA(text *text_re, Oid collation, TrgmPackedGraph **graph, MemoryContext rcontext)
Definition: trgm_regexp.c:517
#define RegExpICaseStrategyNumber
Definition: trgm.h:34
uint16 StrategyNumber
Definition: stratnum.h:22
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:232
#define ARRNELEM(x)
Definition: trgm.h:105
#define PG_GET_COLLATION()
Definition: fmgr.h:155
signed int int32
Definition: c.h:253
#define GETARR(x)
Definition: trgm.h:104
#define GIN_SEARCH_MODE_ALL
Definition: gin.h:35
char * Pointer
Definition: c.h:242
#define ERROR
Definition: elog.h:43
Definition: trgm.h:63
#define LikeStrategyNumber
Definition: trgm.h:31
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
uint32 trgm2int(trgm *ptr)
Definition: trgm_op.c:865
uintptr_t Datum
Definition: postgres.h:374
#define WordSimilarityStrategyNumber
Definition: trgm.h:35
char trgm[3]
Definition: trgm.h:38
#define NULL
Definition: c.h:226
TRGM * generate_trgm(char *str, int slen)
Definition: trgm_op.c:321
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:228
#define Int32GetDatum(X)
Definition: postgres.h:487
void * palloc(Size size)
Definition: mcxt.c:891
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:269
int i
Definition: c.h:434
#define ILikeStrategyNumber
Definition: trgm.h:32
#define elog
Definition: elog.h:219
long val
Definition: informix.c:689
Datum gin_extract_trgm ( PG_FUNCTION_ARGS  )

Definition at line 25 of file trgm_gin.c.

References elog, ERROR, gin_extract_query_trgm(), gin_extract_value_trgm(), PG_NARGS, and PG_RETURN_NULL.

26 {
27  if (PG_NARGS() == 3)
28  return gin_extract_value_trgm(fcinfo);
29  if (PG_NARGS() == 7)
30  return gin_extract_query_trgm(fcinfo);
31  elog(ERROR, "unexpected number of arguments to gin_extract_trgm");
33 }
#define ERROR
Definition: elog.h:43
Datum gin_extract_query_trgm(PG_FUNCTION_ARGS)
Definition: trgm_gin.c:71
Datum gin_extract_value_trgm(PG_FUNCTION_ARGS)
Definition: trgm_gin.c:36
#define PG_NARGS()
Definition: fmgr.h:160
#define elog
Definition: elog.h:219
#define PG_RETURN_NULL()
Definition: fmgr.h:289
Datum gin_extract_value_trgm ( PG_FUNCTION_ARGS  )

Definition at line 36 of file trgm_gin.c.

References ARRNELEM, generate_trgm(), GETARR, i, Int32GetDatum, NULL, palloc(), PG_GETARG_POINTER, PG_GETARG_TEXT_P, PG_RETURN_POINTER, trgm2int(), val, VARDATA, VARHDRSZ, and VARSIZE.

Referenced by gin_extract_trgm().

37 {
38  text *val = (text *) PG_GETARG_TEXT_P(0);
39  int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
40  Datum *entries = NULL;
41  TRGM *trg;
42  int32 trglen;
43 
44  *nentries = 0;
45 
46  trg = generate_trgm(VARDATA(val), VARSIZE(val) - VARHDRSZ);
47  trglen = ARRNELEM(trg);
48 
49  if (trglen > 0)
50  {
51  trgm *ptr;
52  int32 i;
53 
54  *nentries = trglen;
55  entries = (Datum *) palloc(sizeof(Datum) * trglen);
56 
57  ptr = GETARR(trg);
58  for (i = 0; i < trglen; i++)
59  {
60  int32 item = trgm2int(ptr);
61 
62  entries[i] = Int32GetDatum(item);
63  ptr++;
64  }
65  }
66 
67  PG_RETURN_POINTER(entries);
68 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:305
#define VARDATA(PTR)
Definition: postgres.h:305
#define VARSIZE(PTR)
Definition: postgres.h:306
#define VARHDRSZ
Definition: c.h:440
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:232
#define ARRNELEM(x)
Definition: trgm.h:105
signed int int32
Definition: c.h:253
#define GETARR(x)
Definition: trgm.h:104
Definition: trgm.h:63
uint32 trgm2int(trgm *ptr)
Definition: trgm_op.c:865
uintptr_t Datum
Definition: postgres.h:374
char trgm[3]
Definition: trgm.h:38
#define NULL
Definition: c.h:226
TRGM * generate_trgm(char *str, int slen)
Definition: trgm_op.c:321
#define Int32GetDatum(X)
Definition: postgres.h:487
void * palloc(Size size)
Definition: mcxt.c:891
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:269
int i
Definition: c.h:434
long val
Definition: informix.c:689
Datum gin_trgm_consistent ( PG_FUNCTION_ARGS  )

Definition at line 168 of file trgm_gin.c.

References elog, ERROR, i, ILikeStrategyNumber, LikeStrategyNumber, PG_GETARG_INT32, PG_GETARG_POINTER, PG_GETARG_UINT16, PG_RETURN_BOOL, RegExpICaseStrategyNumber, RegExpStrategyNumber, similarity_threshold, SimilarityStrategyNumber, trigramsMatchGraph(), word_similarity_threshold, and WordSimilarityStrategyNumber.

169 {
170  bool *check = (bool *) PG_GETARG_POINTER(0);
171  StrategyNumber strategy = PG_GETARG_UINT16(1);
172 
173  /* text *query = PG_GETARG_TEXT_P(2); */
174  int32 nkeys = PG_GETARG_INT32(3);
175  Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4);
176  bool *recheck = (bool *) PG_GETARG_POINTER(5);
177  bool res;
178  int32 i,
179  ntrue;
180  double nlimit;
181 
182  /* All cases served by this function are inexact */
183  *recheck = true;
184 
185  switch (strategy)
186  {
189  nlimit = (strategy == SimilarityStrategyNumber) ?
191 
192  /* Count the matches */
193  ntrue = 0;
194  for (i = 0; i < nkeys; i++)
195  {
196  if (check[i])
197  ntrue++;
198  }
199 
200  /*--------------------
201  * If DIVUNION is defined then similarity formula is:
202  * c / (len1 + len2 - c)
203  * where c is number of common trigrams and it stands as ntrue in
204  * this code. Here we don't know value of len2 but we can assume
205  * that c (ntrue) is a lower bound of len2, so upper bound of
206  * similarity is:
207  * c / (len1 + c - c) => c / len1
208  * If DIVUNION is not defined then similarity formula is:
209  * c / max(len1, len2)
210  * And again, c (ntrue) is a lower bound of len2, but c <= len1
211  * just by definition and, consequently, upper bound of
212  * similarity is just c / len1.
213  * So, independently on DIVUNION the upper bound formula is the same.
214  */
215  res = (nkeys == 0) ? false :
216  (((((float4) ntrue) / ((float4) nkeys))) >= nlimit);
217  break;
218  case ILikeStrategyNumber:
219 #ifndef IGNORECASE
220  elog(ERROR, "cannot handle ~~* with case-sensitive trigrams");
221 #endif
222  /* FALL THRU */
223  case LikeStrategyNumber:
224  /* Check if all extracted trigrams are presented. */
225  res = true;
226  for (i = 0; i < nkeys; i++)
227  {
228  if (!check[i])
229  {
230  res = false;
231  break;
232  }
233  }
234  break;
236 #ifndef IGNORECASE
237  elog(ERROR, "cannot handle ~* with case-sensitive trigrams");
238 #endif
239  /* FALL THRU */
241  if (nkeys < 1)
242  {
243  /* Regex processing gave no result: do full index scan */
244  res = true;
245  }
246  else
247  res = trigramsMatchGraph((TrgmPackedGraph *) extra_data[0],
248  check);
249  break;
250  default:
251  elog(ERROR, "unrecognized strategy number: %d", strategy);
252  res = false; /* keep compiler quiet */
253  break;
254  }
255 
256  PG_RETURN_BOOL(res);
257 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:225
bool trigramsMatchGraph(TrgmPackedGraph *graph, bool *check)
Definition: trgm_regexp.c:635
#define RegExpStrategyNumber
Definition: trgm.h:33
#define SimilarityStrategyNumber
Definition: trgm.h:29
#define RegExpICaseStrategyNumber
Definition: trgm.h:34
double similarity_threshold
Definition: trgm_op.c:19
uint16 StrategyNumber
Definition: stratnum.h:22
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:232
double word_similarity_threshold
Definition: trgm_op.c:20
signed int int32
Definition: c.h:253
char * Pointer
Definition: c.h:242
#define ERROR
Definition: elog.h:43
#define LikeStrategyNumber
Definition: trgm.h:31
float float4
Definition: c.h:376
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
#define WordSimilarityStrategyNumber
Definition: trgm.h:35
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:228
int i
#define ILikeStrategyNumber
Definition: trgm.h:32
#define elog
Definition: elog.h:219
Datum gin_trgm_triconsistent ( PG_FUNCTION_ARGS  )

Definition at line 266 of file trgm_gin.c.

References Assert, elog, ERROR, GIN_FALSE, GIN_MAYBE, GIN_TRUE, i, ILikeStrategyNumber, LikeStrategyNumber, palloc(), pfree(), PG_GETARG_INT32, PG_GETARG_POINTER, PG_GETARG_UINT16, PG_RETURN_GIN_TERNARY_VALUE, RegExpICaseStrategyNumber, RegExpStrategyNumber, similarity_threshold, SimilarityStrategyNumber, trigramsMatchGraph(), word_similarity_threshold, and WordSimilarityStrategyNumber.

267 {
269  StrategyNumber strategy = PG_GETARG_UINT16(1);
270 
271  /* text *query = PG_GETARG_TEXT_P(2); */
272  int32 nkeys = PG_GETARG_INT32(3);
273  Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4);
275  int32 i,
276  ntrue;
277  bool *boolcheck;
278  double nlimit;
279 
280  switch (strategy)
281  {
284  nlimit = (strategy == SimilarityStrategyNumber) ?
286 
287  /* Count the matches */
288  ntrue = 0;
289  for (i = 0; i < nkeys; i++)
290  {
291  if (check[i] != GIN_FALSE)
292  ntrue++;
293  }
294 
295  /*
296  * See comment in gin_trgm_consistent() about * upper bound
297  * formula
298  */
299  res = (nkeys == 0)
300  ? GIN_FALSE : (((((float4) ntrue) / ((float4) nkeys)) >= nlimit)
301  ? GIN_MAYBE : GIN_FALSE);
302  break;
303  case ILikeStrategyNumber:
304 #ifndef IGNORECASE
305  elog(ERROR, "cannot handle ~~* with case-sensitive trigrams");
306 #endif
307  /* FALL THRU */
308  case LikeStrategyNumber:
309  /* Check if all extracted trigrams are presented. */
310  res = GIN_MAYBE;
311  for (i = 0; i < nkeys; i++)
312  {
313  if (check[i] == GIN_FALSE)
314  {
315  res = GIN_FALSE;
316  break;
317  }
318  }
319  break;
321 #ifndef IGNORECASE
322  elog(ERROR, "cannot handle ~* with case-sensitive trigrams");
323 #endif
324  /* FALL THRU */
326  if (nkeys < 1)
327  {
328  /* Regex processing gave no result: do full index scan */
329  res = GIN_MAYBE;
330  }
331  else
332  {
333  /*
334  * As trigramsMatchGraph implements a monotonic boolean
335  * function, promoting all GIN_MAYBE keys to GIN_TRUE will
336  * give a conservative result.
337  */
338  boolcheck = (bool *) palloc(sizeof(bool) * nkeys);
339  for (i = 0; i < nkeys; i++)
340  boolcheck[i] = (check[i] != GIN_FALSE);
341  if (!trigramsMatchGraph((TrgmPackedGraph *) extra_data[0],
342  boolcheck))
343  res = GIN_FALSE;
344  pfree(boolcheck);
345  }
346  break;
347  default:
348  elog(ERROR, "unrecognized strategy number: %d", strategy);
349  res = GIN_FALSE; /* keep compiler quiet */
350  break;
351  }
352 
353  /* All cases served by this function are inexact */
354  Assert(res != GIN_TRUE);
356 }
#define GIN_TRUE
Definition: gin.h:60
#define PG_GETARG_INT32(n)
Definition: fmgr.h:225
bool trigramsMatchGraph(TrgmPackedGraph *graph, bool *check)
Definition: trgm_regexp.c:635
#define RegExpStrategyNumber
Definition: trgm.h:33
#define SimilarityStrategyNumber
Definition: trgm.h:29
#define GIN_MAYBE
Definition: gin.h:61
#define RegExpICaseStrategyNumber
Definition: trgm.h:34
double similarity_threshold
Definition: trgm_op.c:19
uint16 StrategyNumber
Definition: stratnum.h:22
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:232
double word_similarity_threshold
Definition: trgm_op.c:20
signed int int32
Definition: c.h:253
#define PG_RETURN_GIN_TERNARY_VALUE(x)
Definition: gin.h:66
void pfree(void *pointer)
Definition: mcxt.c:992
char * Pointer
Definition: c.h:242
#define ERROR
Definition: elog.h:43
char GinTernaryValue
Definition: gin.h:57
#define LikeStrategyNumber
Definition: trgm.h:31
float float4
Definition: c.h:376
#define WordSimilarityStrategyNumber
Definition: trgm.h:35
#define Assert(condition)
Definition: c.h:670
#define GIN_FALSE
Definition: gin.h:59
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:228
void * palloc(Size size)
Definition: mcxt.c:891
int i
#define ILikeStrategyNumber
Definition: trgm.h:32
#define elog
Definition: elog.h:219
PG_FUNCTION_INFO_V1 ( gin_extract_trgm  )
PG_FUNCTION_INFO_V1 ( gin_extract_value_trgm  )
PG_FUNCTION_INFO_V1 ( gin_extract_query_trgm  )
PG_FUNCTION_INFO_V1 ( gin_trgm_consistent  )
PG_FUNCTION_INFO_V1 ( gin_trgm_triconsistent  )