PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
ts_utils.h File Reference
#include "nodes/pg_list.h"
#include "tsearch/ts_public.h"
#include "tsearch/ts_type.h"
Include dependency graph for ts_utils.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ParsedWord
 
struct  ParsedText
 
struct  ExecPhraseData
 
struct  QTNode
 

Macros

#define TS_EXEC_EMPTY   (0x00)
 
#define TS_EXEC_CALC_NOT   (0x01)
 
#define TS_EXEC_PHRASE_NO_POS   (0x02)
 
#define TSearchStrategyNumber   1
 
#define TSearchWithClassStrategyNumber   2
 
#define QTN_NEEDFREE   0x01
 
#define QTN_NOCHANGE   0x02
 
#define QTN_WORDFREE   0x04
 
#define TSQS_SIGLEN   (sizeof(TSQuerySign)*BITS_PER_BYTE)
 
#define TSQuerySignGetDatum(X)   Int64GetDatum((int64) (X))
 
#define DatumGetTSQuerySign(X)   ((TSQuerySign) DatumGetInt64(X))
 
#define PG_RETURN_TSQUERYSIGN(X)   return TSQuerySignGetDatum(X)
 
#define PG_GETARG_TSQUERYSIGN(n)   DatumGetTSQuerySign(PG_GETARG_DATUM(n))
 

Typedefs

typedef struct
TSVectorParseStateData
TSVectorParseState
 
typedef struct
TSQueryParserStateData
TSQueryParserState
 
typedef void(* PushFunction )(Datum opaque, TSQueryParserState state, char *token, int tokenlen, int16 tokenweights, bool prefix)
 
typedef struct ExecPhraseData ExecPhraseData
 
typedef bool(* TSExecuteCallback )(void *arg, QueryOperand *val, ExecPhraseData *data)
 
typedef struct QTNode QTNode
 
typedef uint64 TSQuerySign
 

Functions

TSVectorParseState init_tsvector_parser (char *input, bool oprisdelim, bool is_tsquery)
 
void reset_tsvector_parser (TSVectorParseState state, char *input)
 
bool gettoken_tsvector (TSVectorParseState state, char **token, int *len, WordEntryPos **pos, int *poslen, char **endptr)
 
void close_tsvector_parser (TSVectorParseState state)
 
TSQuery parse_tsquery (char *buf, PushFunction pushval, Datum opaque, bool isplain)
 
void pushValue (TSQueryParserState state, char *strval, int lenval, int16 weight, bool prefix)
 
void pushStop (TSQueryParserState state)
 
void pushOperator (TSQueryParserState state, int8 oper, int16 distance)
 
void parsetext (Oid cfgId, ParsedText *prs, char *buf, int32 buflen)
 
void hlparsetext (Oid cfgId, HeadlineParsedText *prs, TSQuery query, char *buf, int32 buflen)
 
textgenerateHeadline (HeadlineParsedText *prs)
 
bool TS_execute (QueryItem *curitem, void *arg, uint32 flags, TSExecuteCallback chkcond)
 
bool tsquery_requires_match (QueryItem *curitem)
 
TSVector make_tsvector (ParsedText *prs)
 
int32 tsCompareString (char *a, int lena, char *b, int lenb, bool prefix)
 
QueryItemclean_NOT (QueryItem *ptr, int32 *len)
 
TSQuery cleanup_tsquery_stopwords (TSQuery in)
 
QTNodeQT2QTN (QueryItem *in, char *operand)
 
TSQuery QTN2QT (QTNode *in)
 
void QTNFree (QTNode *in)
 
void QTNSort (QTNode *in)
 
void QTNTernary (QTNode *in)
 
void QTNBinary (QTNode *in)
 
int QTNodeCompare (QTNode *an, QTNode *bn)
 
QTNodeQTNCopy (QTNode *in)
 
void QTNClearFlags (QTNode *in, uint32 flags)
 
bool QTNEq (QTNode *a, QTNode *b)
 
TSQuerySign makeTSQuerySign (TSQuery a)
 
QTNodefindsubquery (QTNode *root, QTNode *ex, QTNode *subs, bool *isfind)
 

Macro Definition Documentation

#define DatumGetTSQuerySign (   X)    ((TSQuerySign) DatumGetInt64(X))

Definition at line 221 of file ts_utils.h.

Referenced by gtsquery_consistent(), and gtsquery_penalty().

#define PG_GETARG_TSQUERYSIGN (   n)    DatumGetTSQuerySign(PG_GETARG_DATUM(n))

Definition at line 223 of file ts_utils.h.

Referenced by gtsquery_same().

#define PG_RETURN_TSQUERYSIGN (   X)    return TSQuerySignGetDatum(X)

Definition at line 222 of file ts_utils.h.

Referenced by gtsquery_union().

#define QTN_NEEDFREE   0x01

Definition at line 212 of file ts_utils.h.

Referenced by join_tsqueries(), QTNBinary(), QTNCopy(), QTNFree(), QTNTernary(), and tsquery_not().

#define QTN_NOCHANGE   0x02

Definition at line 213 of file ts_utils.h.

Referenced by dofindsubquery(), findeq(), and tsquery_rewrite_query().

#define QTN_WORDFREE   0x04

Definition at line 214 of file ts_utils.h.

Referenced by QTNCopy(), and QTNFree().

#define TS_EXEC_CALC_NOT   (0x01)
#define TS_EXEC_EMPTY   (0x00)

Definition at line 160 of file ts_utils.h.

Referenced by Cover(), and hlCover().

#define TS_EXEC_PHRASE_NO_POS   (0x02)

Definition at line 175 of file ts_utils.h.

Referenced by gin_tsquery_consistent(), gtsvector_consistent(), and TS_phrase_execute().

#define TSearchStrategyNumber   1

Definition at line 192 of file ts_utils.h.

#define TSearchWithClassStrategyNumber   2

Definition at line 193 of file ts_utils.h.

#define TSQS_SIGLEN   (sizeof(TSQuerySign)*BITS_PER_BYTE)

Definition at line 218 of file ts_utils.h.

Referenced by makeTSQuerySign(), and sizebitvec().

#define TSQuerySignGetDatum (   X)    Int64GetDatum((int64) (X))

Definition at line 220 of file ts_utils.h.

Referenced by gtsquery_compress(), and gtsquery_picksplit().

Typedef Documentation

typedef void(* PushFunction)(Datum opaque, TSQueryParserState state, char *token, int tokenlen, int16 tokenweights,bool prefix)

Definition at line 43 of file ts_utils.h.

typedef bool(* TSExecuteCallback)(void *arg, QueryOperand *val, ExecPhraseData *data)

Definition at line 154 of file ts_utils.h.

Definition at line 41 of file ts_utils.h.

Definition at line 216 of file ts_utils.h.

Definition at line 26 of file ts_utils.h.

Function Documentation

QueryItem* clean_NOT ( QueryItem ptr,
int32 len 
)
TSQuery cleanup_tsquery_stopwords ( TSQuery  in)

Definition at line 386 of file tsquery_cleanup.c.

References calcstrlen(), clean_stopword_intree(), COMPUTESIZE, QueryOperand::distance, ereport, errmsg(), GETOPERAND, GETQUERY, HDRSIZETQ, i, QueryOperand::length, maketree(), NOTICE, NULL, palloc(), plaintree(), QI_VAL, SET_VARSIZE, TSQueryData::size, and QueryOperand::type.

Referenced by parse_tsquery().

387 {
388  int32 len,
389  lenstr,
390  commonlen,
391  i;
392  NODE *root;
393  int ladd,
394  radd;
395  TSQuery out;
396  QueryItem *items;
397  char *operands;
398 
399  if (in->size == 0)
400  return in;
401 
402  /* eliminate stop words */
403  root = clean_stopword_intree(maketree(GETQUERY(in)), &ladd, &radd);
404  if (root == NULL)
405  {
406  ereport(NOTICE,
407  (errmsg("text-search query contains only stop words or doesn't contain lexemes, ignored")));
408  out = palloc(HDRSIZETQ);
409  out->size = 0;
410  SET_VARSIZE(out, HDRSIZETQ);
411  return out;
412  }
413 
414  /*
415  * Build TSQuery from plain view
416  */
417 
418  lenstr = calcstrlen(root);
419  items = plaintree(root, &len);
420  commonlen = COMPUTESIZE(len, lenstr);
421 
422  out = palloc(commonlen);
423  SET_VARSIZE(out, commonlen);
424  out->size = len;
425 
426  memcpy(GETQUERY(out), items, len * sizeof(QueryItem));
427 
428  items = GETQUERY(out);
429  operands = GETOPERAND(out);
430  for (i = 0; i < out->size; i++)
431  {
432  QueryOperand *op = (QueryOperand *) &items[i];
433 
434  if (op->type != QI_VAL)
435  continue;
436 
437  memcpy(operands, GETOPERAND(in) + op->distance, op->length);
438  operands[op->length] = '\0';
439  op->distance = operands - GETOPERAND(out);
440  operands += op->length + 1;
441  }
442 
443  return out;
444 }
Definition: _int_bool.c:27
static NODE * clean_stopword_intree(NODE *node, int *ladd, int *radd)
#define QI_VAL
Definition: ts_type.h:134
uint32 distance
Definition: ts_type.h:158
#define GETQUERY(x)
Definition: _int.h:142
signed int int32
Definition: c.h:253
#define GETOPERAND(x)
Definition: ltree.h:118
static QueryItem * plaintree(NODE *root, int *len)
#define ereport(elevel, rest)
Definition: elog.h:122
#define COMPUTESIZE(size)
Definition: _int.h:140
#define NOTICE
Definition: elog.h:37
#define NULL
Definition: c.h:226
static int32 calcstrlen(NODE *node)
uint32 length
Definition: ts_type.h:158
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
int32 size
Definition: ts_type.h:208
int i
QueryItemType type
Definition: ts_type.h:145
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:330
static NODE * maketree(QueryItem *in)
#define HDRSIZETQ
Definition: ts_type.h:214
void close_tsvector_parser ( TSVectorParseState  state)

Definition at line 74 of file tsvector_parser.c.

References pfree(), and TSVectorParseStateData::word.

Referenced by parse_tsquery(), and tsvectorin().

75 {
76  pfree(state->word);
77  pfree(state);
78 }
void pfree(void *pointer)
Definition: mcxt.c:992
QTNode* findsubquery ( QTNode root,
QTNode ex,
QTNode subs,
bool isfind 
)

Definition at line 267 of file tsquery_rewrite.c.

References dofindsubquery().

Referenced by tsquery_rewrite(), and tsquery_rewrite_query().

268 {
269  bool DidFind = false;
270 
271  root = dofindsubquery(root, ex, subs, &DidFind);
272 
273  if (isfind)
274  *isfind = DidFind;
275 
276  return root;
277 }
static QTNode * dofindsubquery(QTNode *root, QTNode *ex, QTNode *subs, bool *isfind)
text* generateHeadline ( HeadlineParsedText prs)

Definition at line 598 of file ts_parse.c.

References HeadlineParsedText::curwords, HeadlineParsedText::fragdelim, HeadlineParsedText::fragdelimlen, HeadlineWordEntry::in, HeadlineWordEntry::len, palloc(), pfree(), repalloc(), HeadlineWordEntry::repeated, HeadlineWordEntry::replace, HeadlineWordEntry::selected, SET_VARSIZE, HeadlineWordEntry::skip, HeadlineParsedText::startsel, HeadlineParsedText::startsellen, HeadlineParsedText::stopsel, HeadlineParsedText::stopsellen, VARHDRSZ, HeadlineWordEntry::word, and HeadlineParsedText::words.

Referenced by ts_headline_byid_opt().

599 {
600  text *out;
601  char *ptr;
602  int len = 128;
603  int numfragments = 0;
604  int16 infrag = 0;
605 
606  HeadlineWordEntry *wrd = prs->words;
607 
608  out = (text *) palloc(len);
609  ptr = ((char *) out) + VARHDRSZ;
610 
611  while (wrd - prs->words < prs->curwords)
612  {
613  while (wrd->len + prs->stopsellen + prs->startsellen + prs->fragdelimlen + (ptr - ((char *) out)) >= len)
614  {
615  int dist = ptr - ((char *) out);
616 
617  len *= 2;
618  out = (text *) repalloc(out, len);
619  ptr = ((char *) out) + dist;
620  }
621 
622  if (wrd->in && !wrd->repeated)
623  {
624  if (!infrag)
625  {
626 
627  /* start of a new fragment */
628  infrag = 1;
629  numfragments++;
630  /* add a fragment delimiter if this is after the first one */
631  if (numfragments > 1)
632  {
633  memcpy(ptr, prs->fragdelim, prs->fragdelimlen);
634  ptr += prs->fragdelimlen;
635  }
636 
637  }
638  if (wrd->replace)
639  {
640  *ptr = ' ';
641  ptr++;
642  }
643  else if (!wrd->skip)
644  {
645  if (wrd->selected)
646  {
647  memcpy(ptr, prs->startsel, prs->startsellen);
648  ptr += prs->startsellen;
649  }
650  memcpy(ptr, wrd->word, wrd->len);
651  ptr += wrd->len;
652  if (wrd->selected)
653  {
654  memcpy(ptr, prs->stopsel, prs->stopsellen);
655  ptr += prs->stopsellen;
656  }
657  }
658  }
659  else if (!wrd->repeated)
660  {
661  if (infrag)
662  infrag = 0;
663  pfree(wrd->word);
664  }
665 
666  wrd++;
667  }
668 
669  SET_VARSIZE(out, ptr - ((char *) out));
670  return out;
671 }
signed short int16
Definition: c.h:252
#define VARHDRSZ
Definition: c.h:440
void pfree(void *pointer)
Definition: mcxt.c:992
HeadlineWordEntry * words
Definition: ts_public.h:52
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1021
void * palloc(Size size)
Definition: mcxt.c:891
Definition: c.h:434
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:330
bool gettoken_tsvector ( TSVectorParseState  state,
char **  token,
int *  len,
WordEntryPos **  pos,
int *  poslen,
char **  endptr 
)

Definition at line 163 of file tsvector_parser.c.

References Assert, TSVectorParseStateData::bufstart, COPYCHAR, elog, ereport, errcode(), errmsg(), ERROR, INPOSINFO, ISOPERATOR, LIMITPOS, NULL, TSVectorParseStateData::oprisdelim, palloc(), pg_mblen(), TSVectorParseStateData::prsbuf, PRSSYNTAXERROR, repalloc(), RESIZEPRSBUF, RETURN_TOKEN, t_isdigit, t_iseq, t_isspace, WAITCHARCMPLX, WAITENDCMPLX, WAITENDWORD, WAITNEXTCHAR, WAITPOSDELIM, WAITPOSINFO, WAITWORD, WEP_GETPOS, WEP_GETWEIGHT, WEP_SETPOS, WEP_SETWEIGHT, and TSVectorParseStateData::word.

Referenced by gettoken_query(), and tsvectorin().

167 {
168  int oldstate = 0;
169  char *curpos = state->word;
170  int statecode = WAITWORD;
171 
172  /*
173  * pos is for collecting the comma delimited list of positions followed by
174  * the actual token.
175  */
176  WordEntryPos *pos = NULL;
177  int npos = 0; /* elements of pos used */
178  int posalen = 0; /* allocated size of pos */
179 
180  while (1)
181  {
182  if (statecode == WAITWORD)
183  {
184  if (*(state->prsbuf) == '\0')
185  return false;
186  else if (t_iseq(state->prsbuf, '\''))
187  statecode = WAITENDCMPLX;
188  else if (t_iseq(state->prsbuf, '\\'))
189  {
190  statecode = WAITNEXTCHAR;
191  oldstate = WAITENDWORD;
192  }
193  else if (state->oprisdelim && ISOPERATOR(state->prsbuf))
195  else if (!t_isspace(state->prsbuf))
196  {
197  COPYCHAR(curpos, state->prsbuf);
198  curpos += pg_mblen(state->prsbuf);
199  statecode = WAITENDWORD;
200  }
201  }
202  else if (statecode == WAITNEXTCHAR)
203  {
204  if (*(state->prsbuf) == '\0')
205  ereport(ERROR,
206  (errcode(ERRCODE_SYNTAX_ERROR),
207  errmsg("there is no escaped character: \"%s\"",
208  state->bufstart)));
209  else
210  {
211  RESIZEPRSBUF;
212  COPYCHAR(curpos, state->prsbuf);
213  curpos += pg_mblen(state->prsbuf);
214  Assert(oldstate != 0);
215  statecode = oldstate;
216  }
217  }
218  else if (statecode == WAITENDWORD)
219  {
220  if (t_iseq(state->prsbuf, '\\'))
221  {
222  statecode = WAITNEXTCHAR;
223  oldstate = WAITENDWORD;
224  }
225  else if (t_isspace(state->prsbuf) || *(state->prsbuf) == '\0' ||
226  (state->oprisdelim && ISOPERATOR(state->prsbuf)))
227  {
228  RESIZEPRSBUF;
229  if (curpos == state->word)
231  *(curpos) = '\0';
232  RETURN_TOKEN;
233  }
234  else if (t_iseq(state->prsbuf, ':'))
235  {
236  if (curpos == state->word)
238  *(curpos) = '\0';
239  if (state->oprisdelim)
240  RETURN_TOKEN;
241  else
242  statecode = INPOSINFO;
243  }
244  else
245  {
246  RESIZEPRSBUF;
247  COPYCHAR(curpos, state->prsbuf);
248  curpos += pg_mblen(state->prsbuf);
249  }
250  }
251  else if (statecode == WAITENDCMPLX)
252  {
253  if (t_iseq(state->prsbuf, '\''))
254  {
255  statecode = WAITCHARCMPLX;
256  }
257  else if (t_iseq(state->prsbuf, '\\'))
258  {
259  statecode = WAITNEXTCHAR;
260  oldstate = WAITENDCMPLX;
261  }
262  else if (*(state->prsbuf) == '\0')
264  else
265  {
266  RESIZEPRSBUF;
267  COPYCHAR(curpos, state->prsbuf);
268  curpos += pg_mblen(state->prsbuf);
269  }
270  }
271  else if (statecode == WAITCHARCMPLX)
272  {
273  if (t_iseq(state->prsbuf, '\''))
274  {
275  RESIZEPRSBUF;
276  COPYCHAR(curpos, state->prsbuf);
277  curpos += pg_mblen(state->prsbuf);
278  statecode = WAITENDCMPLX;
279  }
280  else
281  {
282  RESIZEPRSBUF;
283  *(curpos) = '\0';
284  if (curpos == state->word)
286  if (state->oprisdelim)
287  {
288  /* state->prsbuf+=pg_mblen(state->prsbuf); */
289  RETURN_TOKEN;
290  }
291  else
292  statecode = WAITPOSINFO;
293  continue; /* recheck current character */
294  }
295  }
296  else if (statecode == WAITPOSINFO)
297  {
298  if (t_iseq(state->prsbuf, ':'))
299  statecode = INPOSINFO;
300  else
301  RETURN_TOKEN;
302  }
303  else if (statecode == INPOSINFO)
304  {
305  if (t_isdigit(state->prsbuf))
306  {
307  if (posalen == 0)
308  {
309  posalen = 4;
310  pos = (WordEntryPos *) palloc(sizeof(WordEntryPos) * posalen);
311  npos = 0;
312  }
313  else if (npos + 1 >= posalen)
314  {
315  posalen *= 2;
316  pos = (WordEntryPos *) repalloc(pos, sizeof(WordEntryPos) * posalen);
317  }
318  npos++;
319  WEP_SETPOS(pos[npos - 1], LIMITPOS(atoi(state->prsbuf)));
320  /* we cannot get here in tsquery, so no need for 2 errmsgs */
321  if (WEP_GETPOS(pos[npos - 1]) == 0)
322  ereport(ERROR,
323  (errcode(ERRCODE_SYNTAX_ERROR),
324  errmsg("wrong position info in tsvector: \"%s\"",
325  state->bufstart)));
326  WEP_SETWEIGHT(pos[npos - 1], 0);
327  statecode = WAITPOSDELIM;
328  }
329  else
331  }
332  else if (statecode == WAITPOSDELIM)
333  {
334  if (t_iseq(state->prsbuf, ','))
335  statecode = INPOSINFO;
336  else if (t_iseq(state->prsbuf, 'a') || t_iseq(state->prsbuf, 'A') || t_iseq(state->prsbuf, '*'))
337  {
338  if (WEP_GETWEIGHT(pos[npos - 1]))
340  WEP_SETWEIGHT(pos[npos - 1], 3);
341  }
342  else if (t_iseq(state->prsbuf, 'b') || t_iseq(state->prsbuf, 'B'))
343  {
344  if (WEP_GETWEIGHT(pos[npos - 1]))
346  WEP_SETWEIGHT(pos[npos - 1], 2);
347  }
348  else if (t_iseq(state->prsbuf, 'c') || t_iseq(state->prsbuf, 'C'))
349  {
350  if (WEP_GETWEIGHT(pos[npos - 1]))
352  WEP_SETWEIGHT(pos[npos - 1], 1);
353  }
354  else if (t_iseq(state->prsbuf, 'd') || t_iseq(state->prsbuf, 'D'))
355  {
356  if (WEP_GETWEIGHT(pos[npos - 1]))
358  WEP_SETWEIGHT(pos[npos - 1], 0);
359  }
360  else if (t_isspace(state->prsbuf) ||
361  *(state->prsbuf) == '\0')
362  RETURN_TOKEN;
363  else if (!t_isdigit(state->prsbuf))
365  }
366  else /* internal error */
367  elog(ERROR, "unrecognized state in gettoken_tsvector: %d",
368  statecode);
369 
370  /* get next char */
371  state->prsbuf += pg_mblen(state->prsbuf);
372  }
373 }
#define COPYCHAR(d, s)
Definition: ts_locale.h:63
uint16 WordEntryPos
Definition: ts_type.h:63
#define t_isspace(x)
Definition: ts_locale.h:58
#define WAITPOSDELIM
int errcode(int sqlerrcode)
Definition: elog.c:575
#define t_isdigit(x)
Definition: ts_locale.h:57
#define WEP_SETPOS(x, v)
Definition: ts_type.h:83
#define ERROR
Definition: elog.h:43
#define WAITCHARCMPLX
#define WEP_GETPOS(x)
Definition: ts_type.h:80
#define ISOPERATOR(x)
#define PRSSYNTAXERROR
#define WEP_SETWEIGHT(x, v)
Definition: ts_type.h:82
#define t_iseq(x, c)
Definition: ts_locale.h:61
#define RETURN_TOKEN
#define ereport(elevel, rest)
Definition: elog.h:122
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
#define INPOSINFO
int pg_mblen(const char *mbstr)
Definition: mbutils.c:771
#define WAITNEXTCHAR
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1021
#define WAITPOSINFO
#define RESIZEPRSBUF
#define WAITENDWORD
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define LIMITPOS(x)
Definition: ts_type.h:87
#define elog
Definition: elog.h:219
#define WAITWORD
#define WEP_GETWEIGHT(x)
Definition: ts_type.h:79
#define WAITENDCMPLX
void hlparsetext ( Oid  cfgId,
HeadlineParsedText prs,
TSQuery  query,
char *  buf,
int32  buflen 
)
TSVectorParseState init_tsvector_parser ( char *  input,
bool  oprisdelim,
bool  is_tsquery 
)

Definition at line 45 of file tsvector_parser.c.

References TSVectorParseStateData::bufstart, TSVectorParseStateData::eml, TSVectorParseStateData::is_tsquery, TSVectorParseStateData::len, TSVectorParseStateData::oprisdelim, palloc(), pg_database_encoding_max_length(), TSVectorParseStateData::prsbuf, and TSVectorParseStateData::word.

Referenced by parse_tsquery(), and tsvectorin().

46 {
48 
49  state = (TSVectorParseState) palloc(sizeof(struct TSVectorParseStateData));
50  state->prsbuf = input;
51  state->bufstart = input;
52  state->len = 32;
53  state->word = (char *) palloc(state->len);
55  state->oprisdelim = oprisdelim;
56  state->is_tsquery = is_tsquery;
57 
58  return state;
59 }
struct TSVectorParseStateData * TSVectorParseState
Definition: ts_utils.h:26
int pg_database_encoding_max_length(void)
Definition: wchar.c:1833
Definition: regguts.h:298
void * palloc(Size size)
Definition: mcxt.c:891
TSVector make_tsvector ( ParsedText prs)

Definition at line 145 of file to_tsany.c.

References ParsedWord::alen, ARRPTR, CALCDATASIZE, ParsedText::curwords, elog, ereport, errcode(), errmsg(), ERROR, WordEntry::haspos, i, WordEntry::len, ParsedWord::len, MAXSTRPOS, palloc0(), pfree(), WordEntry::pos, ParsedWord::pos, POSDATAPTR, SET_VARSIZE, SHORTALIGN, TSVectorData::size, STRPTR, uniqueWORD(), WEP_SETPOS, WEP_SETWEIGHT, ParsedWord::word, and ParsedText::words.

Referenced by to_tsvector_byid(), and tsvector_update_trigger().

146 {
147  int i,
148  j,
149  lenstr = 0,
150  totallen;
151  TSVector in;
152  WordEntry *ptr;
153  char *str;
154  int stroff;
155 
156  prs->curwords = uniqueWORD(prs->words, prs->curwords);
157  for (i = 0; i < prs->curwords; i++)
158  {
159  lenstr += prs->words[i].len;
160  if (prs->words[i].alen)
161  {
162  lenstr = SHORTALIGN(lenstr);
163  lenstr += sizeof(uint16) + prs->words[i].pos.apos[0] * sizeof(WordEntryPos);
164  }
165  }
166 
167  if (lenstr > MAXSTRPOS)
168  ereport(ERROR,
169  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
170  errmsg("string is too long for tsvector (%d bytes, max %d bytes)", lenstr, MAXSTRPOS)));
171 
172  totallen = CALCDATASIZE(prs->curwords, lenstr);
173  in = (TSVector) palloc0(totallen);
174  SET_VARSIZE(in, totallen);
175  in->size = prs->curwords;
176 
177  ptr = ARRPTR(in);
178  str = STRPTR(in);
179  stroff = 0;
180  for (i = 0; i < prs->curwords; i++)
181  {
182  ptr->len = prs->words[i].len;
183  ptr->pos = stroff;
184  memcpy(str + stroff, prs->words[i].word, prs->words[i].len);
185  stroff += prs->words[i].len;
186  pfree(prs->words[i].word);
187  if (prs->words[i].alen)
188  {
189  int k = prs->words[i].pos.apos[0];
190  WordEntryPos *wptr;
191 
192  if (k > 0xFFFF)
193  elog(ERROR, "positions array too long");
194 
195  ptr->haspos = 1;
196  stroff = SHORTALIGN(stroff);
197  *(uint16 *) (str + stroff) = (uint16) k;
198  wptr = POSDATAPTR(in, ptr);
199  for (j = 0; j < k; j++)
200  {
201  WEP_SETWEIGHT(wptr[j], 0);
202  WEP_SETPOS(wptr[j], prs->words[i].pos.apos[j + 1]);
203  }
204  stroff += sizeof(uint16) + k * sizeof(WordEntryPos);
205  pfree(prs->words[i].pos.apos);
206  }
207  else
208  ptr->haspos = 0;
209  ptr++;
210  }
211  pfree(prs->words);
212  return in;
213 }
uint16 WordEntryPos
Definition: ts_type.h:63
uint32 len
Definition: ts_type.h:44
int errcode(int sqlerrcode)
Definition: elog.c:575
#define MAXSTRPOS
Definition: ts_type.h:50
#define WEP_SETPOS(x, v)
Definition: ts_type.h:83
int32 curwords
Definition: ts_utils.h:87
#define POSDATAPTR(x, e)
Definition: ts_type.h:111
unsigned short uint16
Definition: c.h:264
void pfree(void *pointer)
Definition: mcxt.c:992
#define ERROR
Definition: elog.h:43
#define WEP_SETWEIGHT(x, v)
Definition: ts_type.h:82
int32 size
Definition: ts_type.h:93
ParsedWord * words
Definition: ts_utils.h:85
uint16 pos
Definition: ts_utils.h:69
uint32 haspos
Definition: ts_type.h:44
#define ereport(elevel, rest)
Definition: elog.h:122
#define CALCDATASIZE(x, lenstr)
Definition: hstore.h:72
void * palloc0(Size size)
Definition: mcxt.c:920
TSVectorData * TSVector
Definition: ts_type.h:98
uint16 len
Definition: ts_utils.h:65
uint32 pos
Definition: ts_type.h:44
uint32 alen
Definition: ts_utils.h:80
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define STRPTR(x)
Definition: hstore.h:76
int i
static int uniqueWORD(ParsedWord *a, int32 l)
Definition: to_tsany.c:59
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:330
#define ARRPTR(x)
Definition: cube.c:26
#define elog
Definition: elog.h:219
#define SHORTALIGN(LEN)
Definition: c.h:579
char * word
Definition: ts_utils.h:79
TSQuerySign makeTSQuerySign ( TSQuery  a)

Definition at line 249 of file tsquery_op.c.

References GETQUERY, i, QI_VAL, QueryItem::qoperand, sign, TSQueryData::size, TSQS_SIGLEN, QueryItem::type, and QueryOperand::valcrc.

Referenced by gtsquery_compress(), and gtsquery_consistent().

250 {
251  int i;
252  QueryItem *ptr = GETQUERY(a);
253  TSQuerySign sign = 0;
254 
255  for (i = 0; i < a->size; i++)
256  {
257  if (ptr->type == QI_VAL)
258  sign |= ((TSQuerySign) 1) << (((unsigned int) ptr->qoperand.valcrc) % TSQS_SIGLEN);
259  ptr++;
260  }
261 
262  return sign;
263 }
#define TSQS_SIGLEN
Definition: ts_utils.h:218
#define QI_VAL
Definition: ts_type.h:134
#define GETQUERY(x)
Definition: _int.h:142
char sign
Definition: informix.c:693
uint64 TSQuerySign
Definition: ts_utils.h:216
int32 valcrc
Definition: ts_type.h:151
QueryItemType type
Definition: ts_type.h:195
int32 size
Definition: ts_type.h:208
int i
QueryOperand qoperand
Definition: ts_type.h:197
TSQuery parse_tsquery ( char *  buf,
PushFunction  pushval,
Datum  opaque,
bool  isplain 
)

Definition at line 605 of file tsquery.c.

References TSQueryParserStateData::buf, buf, TSQueryParserStateData::buffer, cleanup_tsquery_stopwords(), close_tsvector_parser(), COMPUTESIZE, TSQueryParserStateData::count, TSQueryParserStateData::curop, elog, ereport, errcode(), errmsg(), ERROR, findoprnd(), GETOPERAND, GETQUERY, HDRSIZETQ, i, init_tsvector_parser(), TSQueryParserStateData::lenop, lfirst, list_length(), makepol(), NIL, NOTICE, TSQueryParserStateData::op, palloc(), palloc0(), pfree(), TSQueryParserStateData::polstr, QI_OPR, QI_VAL, QI_VALSTOP, SET_VARSIZE, TSQueryData::size, TSQueryParserStateData::state, TSQueryParserStateData::sumlen, TSQUERY_TOO_BIG, QueryItem::type, TSQueryParserStateData::valstate, WAITFIRSTOPERAND, and WAITSINGLEOPERAND.

Referenced by phraseto_tsquery_byid(), plainto_tsquery_byid(), to_tsquery_byid(), and tsqueryin().

609 {
611  int i;
612  TSQuery query;
613  int commonlen;
614  QueryItem *ptr;
615  ListCell *cell;
616  bool needcleanup;
617 
618  /* init state */
619  state.buffer = buf;
620  state.buf = buf;
621  state.state = (isplain) ? WAITSINGLEOPERAND : WAITFIRSTOPERAND;
622  state.count = 0;
623  state.polstr = NIL;
624 
625  /* init value parser's state */
626  state.valstate = init_tsvector_parser(state.buffer, true, true);
627 
628  /* init list of operand */
629  state.sumlen = 0;
630  state.lenop = 64;
631  state.curop = state.op = (char *) palloc(state.lenop);
632  *(state.curop) = '\0';
633 
634  /* parse query & make polish notation (postfix, but in reverse order) */
635  makepol(&state, pushval, opaque);
636 
637  close_tsvector_parser(state.valstate);
638 
639  if (list_length(state.polstr) == 0)
640  {
641  ereport(NOTICE,
642  (errmsg("text-search query doesn't contain lexemes: \"%s\"",
643  state.buffer)));
644  query = (TSQuery) palloc(HDRSIZETQ);
645  SET_VARSIZE(query, HDRSIZETQ);
646  query->size = 0;
647  return query;
648  }
649 
650  if (TSQUERY_TOO_BIG(list_length(state.polstr), state.sumlen))
651  ereport(ERROR,
652  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
653  errmsg("tsquery is too large")));
654  commonlen = COMPUTESIZE(list_length(state.polstr), state.sumlen);
655 
656  /* Pack the QueryItems in the final TSQuery struct to return to caller */
657  query = (TSQuery) palloc0(commonlen);
658  SET_VARSIZE(query, commonlen);
659  query->size = list_length(state.polstr);
660  ptr = GETQUERY(query);
661 
662  /* Copy QueryItems to TSQuery */
663  i = 0;
664  foreach(cell, state.polstr)
665  {
666  QueryItem *item = (QueryItem *) lfirst(cell);
667 
668  switch (item->type)
669  {
670  case QI_VAL:
671  memcpy(&ptr[i], item, sizeof(QueryOperand));
672  break;
673  case QI_VALSTOP:
674  ptr[i].type = QI_VALSTOP;
675  break;
676  case QI_OPR:
677  memcpy(&ptr[i], item, sizeof(QueryOperator));
678  break;
679  default:
680  elog(ERROR, "unrecognized QueryItem type: %d", item->type);
681  }
682  i++;
683  }
684 
685  /* Copy all the operand strings to TSQuery */
686  memcpy((void *) GETOPERAND(query), (void *) state.op, state.sumlen);
687  pfree(state.op);
688 
689  /*
690  * Set left operand pointers for every operator. While we're at it,
691  * detect whether there are any QI_VALSTOP nodes.
692  */
693  findoprnd(ptr, query->size, &needcleanup);
694 
695  /*
696  * If there are QI_VALSTOP nodes, delete them and simplify the tree.
697  */
698  if (needcleanup)
699  query = cleanup_tsquery_stopwords(query);
700 
701  return query;
702 }
#define QI_VALSTOP
Definition: ts_type.h:136
#define NIL
Definition: pg_list.h:69
#define TSQUERY_TOO_BIG(size, lenofoperand)
Definition: ts_type.h:220
#define WAITFIRSTOPERAND
Definition: tsquery.c:63
static void makepol(TSQueryParserState state, PushFunction pushval, Datum opaque)
Definition: tsquery.c:476
void close_tsvector_parser(TSVectorParseState state)
#define WAITSINGLEOPERAND
Definition: tsquery.c:64
TSQueryData * TSQuery
Definition: ts_type.h:212
int errcode(int sqlerrcode)
Definition: elog.c:575
#define QI_VAL
Definition: ts_type.h:134
TSQuery cleanup_tsquery_stopwords(TSQuery in)
#define GETQUERY(x)
Definition: _int.h:142
#define GETOPERAND(x)
Definition: ltree.h:118
void pfree(void *pointer)
Definition: mcxt.c:992
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:65
TSVectorParseState init_tsvector_parser(char *input, bool oprisdelim, bool is_tsquery)
#define ereport(elevel, rest)
Definition: elog.h:122
#define QI_OPR
Definition: ts_type.h:135
QueryItemType type
Definition: ts_type.h:195
void * palloc0(Size size)
Definition: mcxt.c:920
#define COMPUTESIZE(size)
Definition: _int.h:140
#define NOTICE
Definition: elog.h:37
#define lfirst(lc)
Definition: pg_list.h:106
Definition: regguts.h:298
static int list_length(const List *l)
Definition: pg_list.h:89
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
int32 size
Definition: ts_type.h:208
int i
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:330
#define elog
Definition: elog.h:219
#define HDRSIZETQ
Definition: ts_type.h:214
static void findoprnd(QueryItem *ptr, int size, bool *needcleanup)
Definition: tsquery.c:580
void parsetext ( Oid  cfgId,
ParsedText prs,
char *  buf,
int32  buflen 
)
void pushOperator ( TSQueryParserState  state,
int8  oper,
int16  distance 
)

Definition at line 335 of file tsquery.c.

References Assert, QueryOperator::distance, lcons(), OP_AND, OP_NOT, OP_OR, OP_PHRASE, QueryOperator::oper, oper(), palloc0(), TSQueryParserStateData::polstr, QI_OPR, and QueryOperator::type.

Referenced by cleanOpStack(), and pushval_morph().

336 {
337  QueryOperator *tmp;
338 
339  Assert(oper == OP_NOT || oper == OP_AND || oper == OP_OR || oper == OP_PHRASE);
340 
341  tmp = (QueryOperator *) palloc0(sizeof(QueryOperator));
342  tmp->type = QI_OPR;
343  tmp->oper = oper;
344  tmp->distance = (oper == OP_PHRASE) ? distance : 0;
345  /* left is filled in later with findoprnd */
346 
347  state->polstr = lcons(tmp, state->polstr);
348 }
int16 distance
Definition: ts_type.h:183
#define OP_OR
Definition: ts_type.h:168
#define OP_AND
Definition: ts_type.h:167
#define QI_OPR
Definition: ts_type.h:135
void * palloc0(Size size)
Definition: mcxt.c:920
List * lcons(void *datum, List *list)
Definition: list.c:259
QueryItemType type
Definition: ts_type.h:181
#define Assert(condition)
Definition: c.h:670
#define OP_PHRASE
Definition: ts_type.h:169
Operator oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId, bool noError, int location)
Definition: parse_oper.c:375
#define OP_NOT
Definition: ts_type.h:166
void pushStop ( TSQueryParserState  state)

Definition at line 420 of file tsquery.c.

References lcons(), palloc0(), TSQueryParserStateData::polstr, QI_VALSTOP, and QueryOperand::type.

Referenced by pushval_morph().

421 {
422  QueryOperand *tmp;
423 
424  tmp = (QueryOperand *) palloc0(sizeof(QueryOperand));
425  tmp->type = QI_VALSTOP;
426 
427  state->polstr = lcons(tmp, state->polstr);
428 }
#define QI_VALSTOP
Definition: ts_type.h:136
void * palloc0(Size size)
Definition: mcxt.c:920
List * lcons(void *datum, List *list)
Definition: list.c:259
QueryItemType type
Definition: ts_type.h:145
void pushValue ( TSQueryParserState  state,
char *  strval,
int  lenval,
int16  weight,
bool  prefix 
)

Definition at line 384 of file tsquery.c.

References TSQueryParserStateData::buffer, COMP_LEGACY_CRC32, TSQueryParserStateData::curop, ereport, errcode(), errmsg(), ERROR, FIN_LEGACY_CRC32, INIT_LEGACY_CRC32, TSQueryParserStateData::lenop, MAXSTRLEN, TSQueryParserStateData::op, pushValue_internal(), repalloc(), and TSQueryParserStateData::sumlen.

Referenced by pushval_asis(), and pushval_morph().

385 {
386  pg_crc32 valcrc;
387 
388  if (lenval >= MAXSTRLEN)
389  ereport(ERROR,
390  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
391  errmsg("word is too long in tsquery: \"%s\"",
392  state->buffer)));
393 
394  INIT_LEGACY_CRC32(valcrc);
395  COMP_LEGACY_CRC32(valcrc, strval, lenval);
396  FIN_LEGACY_CRC32(valcrc);
397  pushValue_internal(state, valcrc, state->curop - state->op, lenval, weight, prefix);
398 
399  /* append the value string to state.op, enlarging buffer if needed first */
400  while (state->curop - state->op + lenval + 1 >= state->lenop)
401  {
402  int used = state->curop - state->op;
403 
404  state->lenop *= 2;
405  state->op = (char *) repalloc((void *) state->op, state->lenop);
406  state->curop = state->op + used;
407  }
408  memcpy((void *) state->curop, (void *) strval, lenval);
409  state->curop += lenval;
410  *(state->curop) = '\0';
411  state->curop++;
412  state->sumlen += lenval + 1 /* \0 */ ;
413 }
#define INIT_LEGACY_CRC32(crc)
Definition: pg_crc.h:79
int errcode(int sqlerrcode)
Definition: elog.c:575
static void pushValue_internal(TSQueryParserState state, pg_crc32 valcrc, int distance, int lenval, int weight, bool prefix)
Definition: tsquery.c:351
#define FIN_LEGACY_CRC32(crc)
Definition: pg_crc.h:80
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1021
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define COMP_LEGACY_CRC32(crc, data, len)
Definition: pg_crc.h:81
uint32 pg_crc32
Definition: pg_crc.h:37
#define MAXSTRLEN
Definition: ts_type.h:49
QTNode* QT2QTN ( QueryItem in,
char *  operand 
)

Definition at line 24 of file tsquery_util.c.

References check_stack_depth(), QTNode::child, QueryOperand::distance, QueryOperator::left, QTNode::nchild, OP_NOT, QueryOperator::oper, palloc0(), QI_OPR, QueryItem::qoperand, QueryItem::qoperator, QT2QTN(), QTNode::sign, QueryItem::type, QueryOperand::valcrc, QTNode::valnode, and QTNode::word.

Referenced by CompareTSQ(), join_tsqueries(), QT2QTN(), tsquery_not(), tsquery_rewrite(), and tsquery_rewrite_query().

25 {
26  QTNode *node = (QTNode *) palloc0(sizeof(QTNode));
27 
28  /* since this function recurses, it could be driven to stack overflow. */
30 
31  node->valnode = in;
32 
33  if (in->type == QI_OPR)
34  {
35  node->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);
36  node->child[0] = QT2QTN(in + 1, operand);
37  node->sign = node->child[0]->sign;
38  if (in->qoperator.oper == OP_NOT)
39  node->nchild = 1;
40  else
41  {
42  node->nchild = 2;
43  node->child[1] = QT2QTN(in + in->qoperator.left, operand);
44  node->sign |= node->child[1]->sign;
45  }
46  }
47  else if (operand)
48  {
49  node->word = operand + in->qoperand.distance;
50  node->sign = ((uint32) 1) << (((unsigned int) in->qoperand.valcrc) % 32);
51  }
52 
53  return node;
54 }
QueryOperator qoperator
Definition: ts_type.h:196
char * word
Definition: ts_utils.h:206
uint32 sign
Definition: ts_utils.h:207
QTNode * QT2QTN(QueryItem *in, char *operand)
Definition: tsquery_util.c:24
uint32 distance
Definition: ts_type.h:158
void check_stack_depth(void)
Definition: postgres.c:3096
int32 valcrc
Definition: ts_type.h:151
unsigned int uint32
Definition: c.h:265
#define QI_OPR
Definition: ts_type.h:135
QueryItemType type
Definition: ts_type.h:195
void * palloc0(Size size)
Definition: mcxt.c:920
struct QTNode ** child
Definition: ts_utils.h:208
uint32 left
Definition: ts_type.h:184
QueryItem * valnode
Definition: ts_utils.h:203
int32 nchild
Definition: ts_utils.h:205
QueryOperand qoperand
Definition: ts_type.h:197
#define OP_NOT
Definition: ts_type.h:166
TSQuery QTN2QT ( QTNode in)

Definition at line 362 of file tsquery_util.c.

References cntsize(), COMPUTESIZE, QTN2QTState::curitem, QTN2QTState::curoperand, ereport, errcode(), errmsg(), ERROR, fillQT(), GETOPERAND, GETQUERY, QTN2QTState::operand, palloc0(), SET_VARSIZE, TSQueryData::size, and TSQUERY_TOO_BIG.

Referenced by tsquery_and(), tsquery_not(), tsquery_or(), tsquery_phrase_distance(), tsquery_rewrite(), and tsquery_rewrite_query().

363 {
364  TSQuery out;
365  int len;
366  int sumlen = 0,
367  nnode = 0;
369 
370  cntsize(in, &sumlen, &nnode);
371 
372  if (TSQUERY_TOO_BIG(nnode, sumlen))
373  ereport(ERROR,
374  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
375  errmsg("tsquery is too large")));
376  len = COMPUTESIZE(nnode, sumlen);
377 
378  out = (TSQuery) palloc0(len);
379  SET_VARSIZE(out, len);
380  out->size = nnode;
381 
382  state.curitem = GETQUERY(out);
383  state.operand = state.curoperand = GETOPERAND(out);
384 
385  fillQT(&state, in);
386  return out;
387 }
#define TSQUERY_TOO_BIG(size, lenofoperand)
Definition: ts_type.h:220
TSQueryData * TSQuery
Definition: ts_type.h:212
int errcode(int sqlerrcode)
Definition: elog.c:575
static void fillQT(QTN2QTState *state, QTNode *in)
Definition: tsquery_util.c:322
#define GETQUERY(x)
Definition: _int.h:142
QueryItem * curitem
Definition: tsquery_util.c:312
#define GETOPERAND(x)
Definition: ltree.h:118
#define ERROR
Definition: elog.h:43
char * curoperand
Definition: tsquery_util.c:314
#define ereport(elevel, rest)
Definition: elog.h:122
void * palloc0(Size size)
Definition: mcxt.c:920
#define COMPUTESIZE(size)
Definition: _int.h:140
char * operand
Definition: tsquery_util.c:313
int errmsg(const char *fmt,...)
Definition: elog.c:797
int32 size
Definition: ts_type.h:208
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:330
static void cntsize(QTNode *in, int *sumlen, int *nnode)
Definition: tsquery_util.c:291
void QTNBinary ( QTNode in)

Definition at line 249 of file tsquery_util.c.

References check_stack_depth(), QTNode::child, QTNode::flags, i, QTNode::nchild, QueryOperator::oper, palloc0(), QI_OPR, QueryItem::qoperator, QTN_NEEDFREE, QTNBinary(), QTNode::sign, QueryItem::type, and QTNode::valnode.

Referenced by QTNBinary(), tsquery_rewrite(), and tsquery_rewrite_query().

250 {
251  int i;
252 
253  /* since this function recurses, it could be driven to stack overflow. */
255 
256  if (in->valnode->type != QI_OPR)
257  return;
258 
259  for (i = 0; i < in->nchild; i++)
260  QTNBinary(in->child[i]);
261 
262  while (in->nchild > 2)
263  {
264  QTNode *nn = (QTNode *) palloc0(sizeof(QTNode));
265 
266  nn->valnode = (QueryItem *) palloc0(sizeof(QueryItem));
267  nn->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);
268 
269  nn->nchild = 2;
270  nn->flags = QTN_NEEDFREE;
271 
272  nn->child[0] = in->child[0];
273  nn->child[1] = in->child[1];
274  nn->sign = nn->child[0]->sign | nn->child[1]->sign;
275 
276  nn->valnode->type = in->valnode->type;
278 
279  in->child[0] = nn;
280  in->child[1] = in->child[in->nchild - 1];
281  in->nchild--;
282  }
283 }
QueryOperator qoperator
Definition: ts_type.h:196
void QTNBinary(QTNode *in)
Definition: tsquery_util.c:249
uint32 sign
Definition: ts_utils.h:207
void check_stack_depth(void)
Definition: postgres.c:3096
#define QI_OPR
Definition: ts_type.h:135
QueryItemType type
Definition: ts_type.h:195
void * palloc0(Size size)
Definition: mcxt.c:920
struct QTNode ** child
Definition: ts_utils.h:208
#define QTN_NEEDFREE
Definition: ts_utils.h:212
QueryItem * valnode
Definition: ts_utils.h:203
int32 nchild
Definition: ts_utils.h:205
int i
uint32 flags
Definition: ts_utils.h:204
void QTNClearFlags ( QTNode in,
uint32  flags 
)

Definition at line 433 of file tsquery_util.c.

References check_stack_depth(), QTNode::child, QTNode::flags, i, QTNode::nchild, QI_VAL, QTNClearFlags(), QueryItem::type, and QTNode::valnode.

Referenced by QTNClearFlags(), and tsquery_rewrite_query().

434 {
435  /* since this function recurses, it could be driven to stack overflow. */
437 
438  in->flags &= ~flags;
439 
440  if (in->valnode->type != QI_VAL)
441  {
442  int i;
443 
444  for (i = 0; i < in->nchild; i++)
445  QTNClearFlags(in->child[i], flags);
446  }
447 }
#define QI_VAL
Definition: ts_type.h:134
void check_stack_depth(void)
Definition: postgres.c:3096
void QTNClearFlags(QTNode *in, uint32 flags)
Definition: tsquery_util.c:433
QueryItemType type
Definition: ts_type.h:195
struct QTNode ** child
Definition: ts_utils.h:208
QueryItem * valnode
Definition: ts_utils.h:203
int32 nchild
Definition: ts_utils.h:205
int i
uint32 flags
Definition: ts_utils.h:204
QTNode* QTNCopy ( QTNode in)

Definition at line 395 of file tsquery_util.c.

References check_stack_depth(), QTNode::child, QTNode::flags, i, QueryOperand::length, QTNode::nchild, palloc(), QI_VAL, QueryItem::qoperand, QTN_NEEDFREE, QTN_WORDFREE, QTNCopy(), QueryItem::type, QTNode::valnode, and QTNode::word.

Referenced by findeq(), and QTNCopy().

396 {
397  QTNode *out;
398 
399  /* since this function recurses, it could be driven to stack overflow. */
401 
402  out = (QTNode *) palloc(sizeof(QTNode));
403 
404  *out = *in;
405  out->valnode = (QueryItem *) palloc(sizeof(QueryItem));
406  *(out->valnode) = *(in->valnode);
407  out->flags |= QTN_NEEDFREE;
408 
409  if (in->valnode->type == QI_VAL)
410  {
411  out->word = palloc(in->valnode->qoperand.length + 1);
412  memcpy(out->word, in->word, in->valnode->qoperand.length);
413  out->word[in->valnode->qoperand.length] = '\0';
414  out->flags |= QTN_WORDFREE;
415  }
416  else
417  {
418  int i;
419 
420  out->child = (QTNode **) palloc(sizeof(QTNode *) * in->nchild);
421 
422  for (i = 0; i < in->nchild; i++)
423  out->child[i] = QTNCopy(in->child[i]);
424  }
425 
426  return out;
427 }
char * word
Definition: ts_utils.h:206
QTNode * QTNCopy(QTNode *in)
Definition: tsquery_util.c:395
#define QI_VAL
Definition: ts_type.h:134
void check_stack_depth(void)
Definition: postgres.c:3096
QueryItemType type
Definition: ts_type.h:195
#define QTN_WORDFREE
Definition: ts_utils.h:214
struct QTNode ** child
Definition: ts_utils.h:208
#define QTN_NEEDFREE
Definition: ts_utils.h:212
uint32 length
Definition: ts_type.h:158
QueryItem * valnode
Definition: ts_utils.h:203
int32 nchild
Definition: ts_utils.h:205
void * palloc(Size size)
Definition: mcxt.c:891
int i
QueryOperand qoperand
Definition: ts_type.h:197
uint32 flags
Definition: ts_utils.h:204
bool QTNEq ( QTNode a,
QTNode b 
)

Definition at line 182 of file tsquery_util.c.

References QTNodeCompare(), QTNode::sign, and sign.

Referenced by findeq().

183 {
184  uint32 sign = a->sign & b->sign;
185 
186  if (!(sign == a->sign && sign == b->sign))
187  return false;
188 
189  return (QTNodeCompare(a, b) == 0) ? true : false;
190 }
uint32 sign
Definition: ts_utils.h:207
char sign
Definition: informix.c:693
unsigned int uint32
Definition: c.h:265
int QTNodeCompare(QTNode *an, QTNode *bn)
Definition: tsquery_util.c:96
void QTNFree ( QTNode in)

Definition at line 63 of file tsquery_util.c.

References check_stack_depth(), QTNode::child, QTNode::flags, i, QTNode::nchild, pfree(), QI_OPR, QI_VAL, QTN_NEEDFREE, QTN_WORDFREE, QTNFree(), QueryItem::type, QTNode::valnode, and QTNode::word.

Referenced by CompareTSQ(), dofindsubquery(), findeq(), QTNFree(), tsquery_and(), tsquery_not(), tsquery_or(), tsquery_phrase_distance(), tsquery_rewrite(), and tsquery_rewrite_query().

64 {
65  if (!in)
66  return;
67 
68  /* since this function recurses, it could be driven to stack overflow. */
70 
71  if (in->valnode->type == QI_VAL && in->word && (in->flags & QTN_WORDFREE) != 0)
72  pfree(in->word);
73 
74  if (in->valnode->type == QI_OPR)
75  {
76  int i;
77 
78  for (i = 0; i < in->nchild; i++)
79  QTNFree(in->child[i]);
80  }
81  if (in->child)
82  pfree(in->child);
83 
84  if (in->flags & QTN_NEEDFREE)
85  pfree(in->valnode);
86 
87  pfree(in);
88 }
char * word
Definition: ts_utils.h:206
void QTNFree(QTNode *in)
Definition: tsquery_util.c:63
#define QI_VAL
Definition: ts_type.h:134
void pfree(void *pointer)
Definition: mcxt.c:992
void check_stack_depth(void)
Definition: postgres.c:3096
#define QI_OPR
Definition: ts_type.h:135
QueryItemType type
Definition: ts_type.h:195
#define QTN_WORDFREE
Definition: ts_utils.h:214
struct QTNode ** child
Definition: ts_utils.h:208
#define QTN_NEEDFREE
Definition: ts_utils.h:212
QueryItem * valnode
Definition: ts_utils.h:203
int32 nchild
Definition: ts_utils.h:205
int i
uint32 flags
Definition: ts_utils.h:204
int QTNodeCompare ( QTNode an,
QTNode bn 
)

Definition at line 96 of file tsquery_util.c.

References check_stack_depth(), QTNode::child, QueryOperator::distance, elog, ERROR, i, QueryOperand::length, QTNode::nchild, OP_PHRASE, QueryOperator::oper, QI_OPR, QI_VAL, QueryItem::qoperand, QueryItem::qoperator, QTNodeCompare(), tsCompareString(), QueryItem::type, QueryOperand::valcrc, QTNode::valnode, and QTNode::word.

Referenced by cmpQTN(), CompareTSQ(), findeq(), QTNEq(), and QTNodeCompare().

97 {
98  /* since this function recurses, it could be driven to stack overflow. */
100 
101  if (an->valnode->type != bn->valnode->type)
102  return (an->valnode->type > bn->valnode->type) ? -1 : 1;
103 
104  if (an->valnode->type == QI_OPR)
105  {
106  QueryOperator *ao = &an->valnode->qoperator;
107  QueryOperator *bo = &bn->valnode->qoperator;
108 
109  if (ao->oper != bo->oper)
110  return (ao->oper > bo->oper) ? -1 : 1;
111 
112  if (an->nchild != bn->nchild)
113  return (an->nchild > bn->nchild) ? -1 : 1;
114 
115  {
116  int i,
117  res;
118 
119  for (i = 0; i < an->nchild; i++)
120  if ((res = QTNodeCompare(an->child[i], bn->child[i])) != 0)
121  return res;
122  }
123 
124  if (ao->oper == OP_PHRASE && ao->distance != bo->distance)
125  return (ao->distance > bo->distance) ? -1 : 1;
126 
127  return 0;
128  }
129  else if (an->valnode->type == QI_VAL)
130  {
131  QueryOperand *ao = &an->valnode->qoperand;
132  QueryOperand *bo = &bn->valnode->qoperand;
133 
134  if (ao->valcrc != bo->valcrc)
135  {
136  return (ao->valcrc > bo->valcrc) ? -1 : 1;
137  }
138 
139  return tsCompareString(an->word, ao->length, bn->word, bo->length, false);
140  }
141  else
142  {
143  elog(ERROR, "unrecognized QueryItem type: %d", an->valnode->type);
144  return 0; /* keep compiler quiet */
145  }
146 }
QueryOperator qoperator
Definition: ts_type.h:196
char * word
Definition: ts_utils.h:206
#define QI_VAL
Definition: ts_type.h:134
int16 distance
Definition: ts_type.h:183
#define ERROR
Definition: elog.h:43
void check_stack_depth(void)
Definition: postgres.c:3096
int32 valcrc
Definition: ts_type.h:151
#define QI_OPR
Definition: ts_type.h:135
QueryItemType type
Definition: ts_type.h:195
#define OP_PHRASE
Definition: ts_type.h:169
int32 tsCompareString(char *a, int lena, char *b, int lenb, bool prefix)
Definition: tsvector_op.c:1160
struct QTNode ** child
Definition: ts_utils.h:208
uint32 length
Definition: ts_type.h:158
QueryItem * valnode
Definition: ts_utils.h:203
int32 nchild
Definition: ts_utils.h:205
int i
int QTNodeCompare(QTNode *an, QTNode *bn)
Definition: tsquery_util.c:96
#define elog
Definition: elog.h:219
QueryOperand qoperand
Definition: ts_type.h:197
void QTNSort ( QTNode in)

Definition at line 162 of file tsquery_util.c.

References check_stack_depth(), QTNode::child, cmpQTN(), i, QTNode::nchild, OP_PHRASE, QueryOperator::oper, QI_OPR, QueryItem::qoperator, qsort, QTNSort(), QueryItem::type, and QTNode::valnode.

Referenced by findeq(), QTNSort(), tsquery_rewrite(), and tsquery_rewrite_query().

163 {
164  int i;
165 
166  /* since this function recurses, it could be driven to stack overflow. */
168 
169  if (in->valnode->type != QI_OPR)
170  return;
171 
172  for (i = 0; i < in->nchild; i++)
173  QTNSort(in->child[i]);
174  if (in->nchild > 1 && in->valnode->qoperator.oper != OP_PHRASE)
175  qsort((void *) in->child, in->nchild, sizeof(QTNode *), cmpQTN);
176 }
QueryOperator qoperator
Definition: ts_type.h:196
void check_stack_depth(void)
Definition: postgres.c:3096
void QTNSort(QTNode *in)
Definition: tsquery_util.c:162
#define QI_OPR
Definition: ts_type.h:135
QueryItemType type
Definition: ts_type.h:195
#define OP_PHRASE
Definition: ts_type.h:169
struct QTNode ** child
Definition: ts_utils.h:208
QueryItem * valnode
Definition: ts_utils.h:203
int32 nchild
Definition: ts_utils.h:205
int i
#define qsort(a, b, c, d)
Definition: port.h:440
static int cmpQTN(const void *a, const void *b)
Definition: tsquery_util.c:152
void QTNTernary ( QTNode in)

Definition at line 200 of file tsquery_util.c.

References check_stack_depth(), QTNode::child, QTNode::flags, i, memmove, QTNode::nchild, OP_AND, OP_OR, QueryOperator::oper, pfree(), QI_OPR, QueryItem::qoperator, QTN_NEEDFREE, QTNTernary(), repalloc(), QueryItem::type, and QTNode::valnode.

Referenced by QTNTernary(), tsquery_rewrite(), and tsquery_rewrite_query().

201 {
202  int i;
203 
204  /* since this function recurses, it could be driven to stack overflow. */
206 
207  if (in->valnode->type != QI_OPR)
208  return;
209 
210  for (i = 0; i < in->nchild; i++)
211  QTNTernary(in->child[i]);
212 
213  /* Only AND and OR are associative, so don't flatten other node types */
214  if (in->valnode->qoperator.oper != OP_AND &&
215  in->valnode->qoperator.oper != OP_OR)
216  return;
217 
218  for (i = 0; i < in->nchild; i++)
219  {
220  QTNode *cc = in->child[i];
221 
222  if (cc->valnode->type == QI_OPR &&
224  {
225  int oldnchild = in->nchild;
226 
227  in->nchild += cc->nchild - 1;
228  in->child = (QTNode **) repalloc(in->child, in->nchild * sizeof(QTNode *));
229 
230  if (i + 1 != oldnchild)
231  memmove(in->child + i + cc->nchild, in->child + i + 1,
232  (oldnchild - i - 1) * sizeof(QTNode *));
233 
234  memcpy(in->child + i, cc->child, cc->nchild * sizeof(QTNode *));
235  i += cc->nchild - 1;
236 
237  if (cc->flags & QTN_NEEDFREE)
238  pfree(cc->valnode);
239  pfree(cc);
240  }
241  }
242 }
void QTNTernary(QTNode *in)
Definition: tsquery_util.c:200
QueryOperator qoperator
Definition: ts_type.h:196
#define OP_OR
Definition: ts_type.h:168
#define OP_AND
Definition: ts_type.h:167
void pfree(void *pointer)
Definition: mcxt.c:992
#define memmove(d, s, c)
Definition: c.h:1057
void check_stack_depth(void)
Definition: postgres.c:3096
#define QI_OPR
Definition: ts_type.h:135
QueryItemType type
Definition: ts_type.h:195
struct QTNode ** child
Definition: ts_utils.h:208
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1021
#define QTN_NEEDFREE
Definition: ts_utils.h:212
QueryItem * valnode
Definition: ts_utils.h:203
int32 nchild
Definition: ts_utils.h:205
int i
uint32 flags
Definition: ts_utils.h:204
void reset_tsvector_parser ( TSVectorParseState  state,
char *  input 
)

Definition at line 65 of file tsvector_parser.c.

References TSVectorParseStateData::prsbuf.

Referenced by gettoken_query().

66 {
67  state->prsbuf = input;
68 }
bool TS_execute ( QueryItem curitem,
void *  arg,
uint32  flags,
TSExecuteCallback  chkcond 
)

Definition at line 1815 of file tsvector_op.c.

References check_stack_depth(), elog, ERROR, QueryOperator::left, NULL, OP_AND, OP_NOT, OP_OR, OP_PHRASE, QueryOperator::oper, QI_VAL, QueryItem::qoperator, TS_EXEC_CALC_NOT, TS_execute(), TS_phrase_execute(), and QueryItem::type.

Referenced by Cover(), gin_tsquery_consistent(), gtsvector_consistent(), hlCover(), TS_execute(), and ts_match_vq().

1817 {
1818  /* since this function recurses, it could be driven to stack overflow */
1820 
1821  if (curitem->type == QI_VAL)
1822  return chkcond(arg, (QueryOperand *) curitem,
1823  NULL /* we don't need position info */ );
1824 
1825  switch (curitem->qoperator.oper)
1826  {
1827  case OP_NOT:
1828  if (flags & TS_EXEC_CALC_NOT)
1829  return !TS_execute(curitem + 1, arg, flags, chkcond);
1830  else
1831  return true;
1832 
1833  case OP_AND:
1834  if (TS_execute(curitem + curitem->qoperator.left, arg, flags, chkcond))
1835  return TS_execute(curitem + 1, arg, flags, chkcond);
1836  else
1837  return false;
1838 
1839  case OP_OR:
1840  if (TS_execute(curitem + curitem->qoperator.left, arg, flags, chkcond))
1841  return true;
1842  else
1843  return TS_execute(curitem + 1, arg, flags, chkcond);
1844 
1845  case OP_PHRASE:
1846  return TS_phrase_execute(curitem, arg, flags, chkcond, NULL);
1847 
1848  default:
1849  elog(ERROR, "unrecognized operator: %d", curitem->qoperator.oper);
1850  }
1851 
1852  /* not reachable, but keep compiler quiet */
1853  return false;
1854 }
bool TS_execute(QueryItem *curitem, void *arg, uint32 flags, TSExecuteCallback chkcond)
Definition: tsvector_op.c:1815
QueryOperator qoperator
Definition: ts_type.h:196
#define TS_EXEC_CALC_NOT
Definition: ts_utils.h:168
#define QI_VAL
Definition: ts_type.h:134
#define OP_OR
Definition: ts_type.h:168
#define OP_AND
Definition: ts_type.h:167
#define ERROR
Definition: elog.h:43
void check_stack_depth(void)
Definition: postgres.c:3096
QueryItemType type
Definition: ts_type.h:195
#define NULL
Definition: c.h:226
#define OP_PHRASE
Definition: ts_type.h:169
uint32 left
Definition: ts_type.h:184
void * arg
static bool TS_phrase_execute(QueryItem *curitem, void *arg, uint32 flags, TSExecuteCallback chkcond, ExecPhraseData *data)
Definition: tsvector_op.c:1572
#define elog
Definition: elog.h:219
#define OP_NOT
Definition: ts_type.h:166
int32 tsCompareString ( char *  a,
int  lena,
char *  b,
int  lenb,
bool  prefix 
)

Definition at line 1160 of file tsvector_op.c.

References cmp(), and Min.

Referenced by checkcondition_str(), compare_text_lexemes(), compareentry(), compareQueryOperand(), compareWORD(), gin_cmp_prefix(), gin_cmp_tslexeme(), hlfinditem(), QTNodeCompare(), silly_cmp_tsvector(), and tsvector_bsearch().

1161 {
1162  int cmp;
1163 
1164  if (lena == 0)
1165  {
1166  if (prefix)
1167  cmp = 0; /* empty string is prefix of anything */
1168  else
1169  cmp = (lenb > 0) ? -1 : 0;
1170  }
1171  else if (lenb == 0)
1172  {
1173  cmp = (lena > 0) ? 1 : 0;
1174  }
1175  else
1176  {
1177  cmp = memcmp(a, b, Min(lena, lenb));
1178 
1179  if (prefix)
1180  {
1181  if (cmp == 0 && lena > lenb)
1182  cmp = 1; /* a is longer, so not a prefix of b */
1183  }
1184  else if (cmp == 0 && lena != lenb)
1185  {
1186  cmp = (lena < lenb) ? -1 : 1;
1187  }
1188  }
1189 
1190  return cmp;
1191 }
#define Min(x, y)
Definition: c.h:801
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742
bool tsquery_requires_match ( QueryItem curitem)

Definition at line 1865 of file tsvector_op.c.

References check_stack_depth(), elog, ERROR, QueryOperator::left, OP_AND, OP_NOT, OP_OR, OP_PHRASE, QueryOperator::oper, QI_VAL, QueryItem::qoperator, tsquery_requires_match(), and QueryItem::type.

Referenced by gin_extract_tsquery(), and tsquery_requires_match().

1866 {
1867  /* since this function recurses, it could be driven to stack overflow */
1869 
1870  if (curitem->type == QI_VAL)
1871  return true;
1872 
1873  switch (curitem->qoperator.oper)
1874  {
1875  case OP_NOT:
1876 
1877  /*
1878  * Assume there are no required matches underneath a NOT. For
1879  * some cases with nested NOTs, we could prove there's a required
1880  * match, but it seems unlikely to be worth the trouble.
1881  */
1882  return false;
1883 
1884  case OP_PHRASE:
1885 
1886  /*
1887  * Treat OP_PHRASE as OP_AND here
1888  */
1889  case OP_AND:
1890  /* If either side requires a match, we're good */
1891  if (tsquery_requires_match(curitem + curitem->qoperator.left))
1892  return true;
1893  else
1894  return tsquery_requires_match(curitem + 1);
1895 
1896  case OP_OR:
1897  /* Both sides must require a match */
1898  if (tsquery_requires_match(curitem + curitem->qoperator.left))
1899  return tsquery_requires_match(curitem + 1);
1900  else
1901  return false;
1902 
1903  default:
1904  elog(ERROR, "unrecognized operator: %d", curitem->qoperator.oper);
1905  }
1906 
1907  /* not reachable, but keep compiler quiet */
1908  return false;
1909 }
QueryOperator qoperator
Definition: ts_type.h:196
bool tsquery_requires_match(QueryItem *curitem)
Definition: tsvector_op.c:1865
#define QI_VAL
Definition: ts_type.h:134
#define OP_OR
Definition: ts_type.h:168
#define OP_AND
Definition: ts_type.h:167
#define ERROR
Definition: elog.h:43
void check_stack_depth(void)
Definition: postgres.c:3096
QueryItemType type
Definition: ts_type.h:195
#define OP_PHRASE
Definition: ts_type.h:169
uint32 left
Definition: ts_type.h:184
#define elog
Definition: elog.h:219
#define OP_NOT
Definition: ts_type.h:166