PostgreSQL Source Code git master
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 P_TSV_OPR_IS_DELIM   (1 << 0)
 
#define P_TSV_IS_TSQUERY   (1 << 1)
 
#define P_TSV_IS_WEB   (1 << 2)
 
#define ISOPERATOR(x)
 
#define P_TSQ_PLAIN   (1 << 0)
 
#define P_TSQ_WEB   (1 << 1)
 
#define TS_EXEC_EMPTY   (0x00)
 
#define TS_EXEC_SKIP_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 PG_RETURN_TSQUERYSIGN(X)   return TSQuerySignGetDatum(X)
 
#define PG_GETARG_TSQUERYSIGN(n)   DatumGetTSQuerySign(PG_GETARG_DATUM(n))
 

Typedefs

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

Enumerations

enum  TSTernaryValue { TS_NO , TS_YES , TS_MAYBE }
 

Functions

TSVectorParseState init_tsvector_parser (char *input, int flags, Node *escontext)
 
void reset_tsvector_parser (TSVectorParseState state, char *input)
 
bool gettoken_tsvector (TSVectorParseState state, char **strval, int *lenval, WordEntryPos **pos_ptr, int *poslen, char **endptr)
 
void close_tsvector_parser (TSVectorParseState state)
 
TSQuery parse_tsquery (char *buf, PushFunction pushval, Datum opaque, int flags, Node *escontext)
 
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)
 
TSTernaryValue TS_execute_ternary (QueryItem *curitem, void *arg, uint32 flags, TSExecuteCallback chkcond)
 
ListTS_execute_locations (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, bool noisy)
 
static Datum TSQuerySignGetDatum (TSQuerySign X)
 
static TSQuerySign DatumGetTSQuerySign (Datum X)
 
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

◆ ISOPERATOR

#define ISOPERATOR (   x)
Value:
( pg_mblen(x) == 1 && ( *(x) == '!' || \
*(x) == '&' || \
*(x) == '|' || \
*(x) == '(' || \
*(x) == ')' || \
*(x) == '<' \
) )
int x
Definition: isn.c:72
int pg_mblen(const char *mbstr)
Definition: mbutils.c:1023

Definition at line 43 of file ts_utils.h.

◆ P_TSQ_PLAIN

#define P_TSQ_PLAIN   (1 << 0)

Definition at line 64 of file ts_utils.h.

◆ P_TSQ_WEB

#define P_TSQ_WEB   (1 << 1)

Definition at line 65 of file ts_utils.h.

◆ P_TSV_IS_TSQUERY

#define P_TSV_IS_TSQUERY   (1 << 1)

Definition at line 30 of file ts_utils.h.

◆ P_TSV_IS_WEB

#define P_TSV_IS_WEB   (1 << 2)

Definition at line 31 of file ts_utils.h.

◆ P_TSV_OPR_IS_DELIM

#define P_TSV_OPR_IS_DELIM   (1 << 0)

Definition at line 29 of file ts_utils.h.

◆ PG_GETARG_TSQUERYSIGN

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

Definition at line 266 of file ts_utils.h.

◆ PG_RETURN_TSQUERYSIGN

#define PG_RETURN_TSQUERYSIGN (   X)    return TSQuerySignGetDatum(X)

Definition at line 265 of file ts_utils.h.

◆ QTN_NEEDFREE

#define QTN_NEEDFREE   0x01

Definition at line 245 of file ts_utils.h.

◆ QTN_NOCHANGE

#define QTN_NOCHANGE   0x02

Definition at line 246 of file ts_utils.h.

◆ QTN_WORDFREE

#define QTN_WORDFREE   0x04

Definition at line 247 of file ts_utils.h.

◆ TS_EXEC_EMPTY

#define TS_EXEC_EMPTY   (0x00)

Definition at line 188 of file ts_utils.h.

◆ TS_EXEC_PHRASE_NO_POS

#define TS_EXEC_PHRASE_NO_POS   (0x02)

Definition at line 202 of file ts_utils.h.

◆ TS_EXEC_SKIP_NOT

#define TS_EXEC_SKIP_NOT   (0x01)

Definition at line 195 of file ts_utils.h.

◆ TSearchStrategyNumber

#define TSearchStrategyNumber   1

Definition at line 225 of file ts_utils.h.

◆ TSearchWithClassStrategyNumber

#define TSearchWithClassStrategyNumber   2

Definition at line 226 of file ts_utils.h.

◆ TSQS_SIGLEN

#define TSQS_SIGLEN   (sizeof(TSQuerySign)*BITS_PER_BYTE)

Definition at line 251 of file ts_utils.h.

Typedef Documentation

◆ ExecPhraseData

◆ PushFunction

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

Definition at line 57 of file ts_utils.h.

◆ QTNode

typedef struct QTNode QTNode

◆ TSExecuteCallback

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

Definition at line 182 of file ts_utils.h.

◆ TSQueryParserState

Definition at line 55 of file ts_utils.h.

◆ TSQuerySign

Definition at line 249 of file ts_utils.h.

◆ TSVectorParseState

Definition at line 26 of file ts_utils.h.

Enumeration Type Documentation

◆ TSTernaryValue

Enumerator
TS_NO 
TS_YES 
TS_MAYBE 

Definition at line 132 of file ts_utils.h.

133{
134 TS_NO, /* definitely no match */
135 TS_YES, /* definitely does match */
136 TS_MAYBE, /* can't verify match for lack of pos data */
TSTernaryValue
Definition: ts_utils.h:133
@ TS_MAYBE
Definition: ts_utils.h:136
@ TS_NO
Definition: ts_utils.h:134
@ TS_YES
Definition: ts_utils.h:135

Function Documentation

◆ clean_NOT()

QueryItem * clean_NOT ( QueryItem ptr,
int32 len 
)

◆ cleanup_tsquery_stopwords()

TSQuery cleanup_tsquery_stopwords ( TSQuery  in,
bool  noisy 
)

Definition at line 387 of file tsquery_cleanup.c.

388{
389 int32 len,
390 lenstr,
391 commonlen,
392 i;
393 NODE *root;
394 int ladd,
395 radd;
396 TSQuery out;
398 char *operands;
399
400 if (in->size == 0)
401 return in;
402
403 /* eliminate stop words */
404 root = clean_stopword_intree(maketree(GETQUERY(in)), &ladd, &radd);
405 if (root == NULL)
406 {
407 if (noisy)
409 (errmsg("text-search query contains only stop words or doesn't contain lexemes, ignored")));
410 out = palloc(HDRSIZETQ);
411 out->size = 0;
413 return out;
414 }
415
416 /*
417 * Build TSQuery from plain view
418 */
419
420 lenstr = calcstrlen(root);
421 items = plaintree(root, &len);
422 commonlen = COMPUTESIZE(len, lenstr);
423
424 out = palloc(commonlen);
425 SET_VARSIZE(out, commonlen);
426 out->size = len;
427
428 memcpy(GETQUERY(out), items, len * sizeof(QueryItem));
429
430 items = GETQUERY(out);
431 operands = GETOPERAND(out);
432 for (i = 0; i < out->size; i++)
433 {
434 QueryOperand *op = (QueryOperand *) &items[i];
435
436 if (op->type != QI_VAL)
437 continue;
438
439 memcpy(operands, GETOPERAND(in) + op->distance, op->length);
440 operands[op->length] = '\0';
441 op->distance = operands - GETOPERAND(out);
442 operands += op->length + 1;
443 }
444
445 return out;
446}
#define COMPUTESIZE(size)
Definition: _int.h:155
#define GETQUERY(x)
Definition: _int.h:157
int32_t int32
Definition: c.h:498
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define NOTICE
Definition: elog.h:35
#define ereport(elevel,...)
Definition: elog.h:149
int i
Definition: isn.c:74
#define GETOPERAND(x)
Definition: ltree.h:165
void * palloc(Size size)
Definition: mcxt.c:1317
const void size_t len
tree ctl root
Definition: radixtree.h:1857
Definition: _int_bool.c:26
QueryItemType type
Definition: ts_type.h:158
uint32 distance
Definition: ts_type.h:172
uint32 length
Definition: ts_type.h:171
int32 size
Definition: ts_type.h:221
static ItemArray items
Definition: test_tidstore.c:48
#define HDRSIZETQ
Definition: ts_type.h:227
#define QI_VAL
Definition: ts_type.h:149
static NODE * maketree(QueryItem *in)
static QueryItem * plaintree(NODE *root, int *len)
static int32 calcstrlen(NODE *node)
static NODE * clean_stopword_intree(NODE *node, int *ladd, int *radd)
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305

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

Referenced by parse_tsquery().

◆ close_tsvector_parser()

void close_tsvector_parser ( TSVectorParseState  state)

Definition at line 90 of file tsvector_parser.c.

91{
92 pfree(state->word);
93 pfree(state);
94}
void pfree(void *pointer)
Definition: mcxt.c:1524
Definition: regguts.h:323

References pfree().

Referenced by parse_tsquery(), and tsvectorin().

◆ DatumGetTSQuerySign()

static TSQuerySign DatumGetTSQuerySign ( Datum  X)
inlinestatic

Definition at line 260 of file ts_utils.h.

261{
262 return (TSQuerySign) DatumGetInt64(X);
263}
static int64 DatumGetInt64(Datum X)
Definition: postgres.h:390
uint64 TSQuerySign
Definition: ts_utils.h:249

References DatumGetInt64().

Referenced by gtsquery_consistent(), and gtsquery_penalty().

◆ findsubquery()

QTNode * findsubquery ( QTNode root,
QTNode ex,
QTNode subs,
bool *  isfind 
)

Definition at line 267 of file tsquery_rewrite.c.

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)

References dofindsubquery(), and root.

Referenced by tsquery_rewrite(), and tsquery_rewrite_query().

◆ generateHeadline()

text * generateHeadline ( HeadlineParsedText prs)

Definition at line 607 of file ts_parse.c.

608{
609 text *out;
610 char *ptr;
611 int len = 128;
612 int numfragments = 0;
613 int16 infrag = 0;
614
615 HeadlineWordEntry *wrd = prs->words;
616
617 out = (text *) palloc(len);
618 ptr = ((char *) out) + VARHDRSZ;
619
620 while (wrd - prs->words < prs->curwords)
621 {
622 while (wrd->len + prs->stopsellen + prs->startsellen + prs->fragdelimlen + (ptr - ((char *) out)) >= len)
623 {
624 int dist = ptr - ((char *) out);
625
626 len *= 2;
627 out = (text *) repalloc(out, len);
628 ptr = ((char *) out) + dist;
629 }
630
631 if (wrd->in && !wrd->repeated)
632 {
633 if (!infrag)
634 {
635
636 /* start of a new fragment */
637 infrag = 1;
638 numfragments++;
639 /* add a fragment delimiter if this is after the first one */
640 if (numfragments > 1)
641 {
642 memcpy(ptr, prs->fragdelim, prs->fragdelimlen);
643 ptr += prs->fragdelimlen;
644 }
645 }
646 if (wrd->replace)
647 {
648 *ptr = ' ';
649 ptr++;
650 }
651 else if (!wrd->skip)
652 {
653 if (wrd->selected)
654 {
655 memcpy(ptr, prs->startsel, prs->startsellen);
656 ptr += prs->startsellen;
657 }
658 memcpy(ptr, wrd->word, wrd->len);
659 ptr += wrd->len;
660 if (wrd->selected)
661 {
662 memcpy(ptr, prs->stopsel, prs->stopsellen);
663 ptr += prs->stopsellen;
664 }
665 }
666 }
667 else if (!wrd->repeated)
668 {
669 if (infrag)
670 infrag = 0;
671 pfree(wrd->word);
672 }
673
674 wrd++;
675 }
676
677 SET_VARSIZE(out, ptr - ((char *) out));
678 return out;
679}
#define VARHDRSZ
Definition: c.h:663
int16_t int16
Definition: c.h:497
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1544
HeadlineWordEntry * words
Definition: ts_public.h:76
Definition: c.h:658

References HeadlineParsedText::curwords, HeadlineParsedText::fragdelim, HeadlineParsedText::fragdelimlen, HeadlineWordEntry::in, HeadlineWordEntry::len, 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 headline_json_value(), and ts_headline_byid_opt().

◆ gettoken_tsvector()

bool gettoken_tsvector ( TSVectorParseState  state,
char **  strval,
int *  lenval,
WordEntryPos **  pos_ptr,
int *  poslen,
char **  endptr 
)

Definition at line 176 of file tsvector_parser.c.

180{
181 int oldstate = 0;
182 char *curpos = state->word;
183 int statecode = WAITWORD;
184
185 /*
186 * pos is for collecting the comma delimited list of positions followed by
187 * the actual token.
188 */
189 WordEntryPos *pos = NULL;
190 int npos = 0; /* elements of pos used */
191 int posalen = 0; /* allocated size of pos */
192
193 while (1)
194 {
195 if (statecode == WAITWORD)
196 {
197 if (*(state->prsbuf) == '\0')
198 return false;
199 else if (!state->is_web && t_iseq(state->prsbuf, '\''))
200 statecode = WAITENDCMPLX;
201 else if (!state->is_web && t_iseq(state->prsbuf, '\\'))
202 {
203 statecode = WAITNEXTCHAR;
204 oldstate = WAITENDWORD;
205 }
206 else if ((state->oprisdelim && ISOPERATOR(state->prsbuf)) ||
207 (state->is_web && t_iseq(state->prsbuf, '"')))
209 else if (!isspace((unsigned char) *state->prsbuf))
210 {
211 COPYCHAR(curpos, state->prsbuf);
212 curpos += pg_mblen(state->prsbuf);
213 statecode = WAITENDWORD;
214 }
215 }
216 else if (statecode == WAITNEXTCHAR)
217 {
218 if (*(state->prsbuf) == '\0')
219 ereturn(state->escontext, false,
220 (errcode(ERRCODE_SYNTAX_ERROR),
221 errmsg("there is no escaped character: \"%s\"",
222 state->bufstart)));
223 else
224 {
226 COPYCHAR(curpos, state->prsbuf);
227 curpos += pg_mblen(state->prsbuf);
228 Assert(oldstate != 0);
229 statecode = oldstate;
230 }
231 }
232 else if (statecode == WAITENDWORD)
233 {
234 if (!state->is_web && t_iseq(state->prsbuf, '\\'))
235 {
236 statecode = WAITNEXTCHAR;
237 oldstate = WAITENDWORD;
238 }
239 else if (isspace((unsigned char) *state->prsbuf) || *(state->prsbuf) == '\0' ||
240 (state->oprisdelim && ISOPERATOR(state->prsbuf)) ||
241 (state->is_web && t_iseq(state->prsbuf, '"')))
242 {
244 if (curpos == state->word)
246 *(curpos) = '\0';
248 }
249 else if (t_iseq(state->prsbuf, ':'))
250 {
251 if (curpos == state->word)
253 *(curpos) = '\0';
254 if (state->oprisdelim)
256 else
257 statecode = INPOSINFO;
258 }
259 else
260 {
262 COPYCHAR(curpos, state->prsbuf);
263 curpos += pg_mblen(state->prsbuf);
264 }
265 }
266 else if (statecode == WAITENDCMPLX)
267 {
268 if (!state->is_web && t_iseq(state->prsbuf, '\''))
269 {
270 statecode = WAITCHARCMPLX;
271 }
272 else if (!state->is_web && t_iseq(state->prsbuf, '\\'))
273 {
274 statecode = WAITNEXTCHAR;
275 oldstate = WAITENDCMPLX;
276 }
277 else if (*(state->prsbuf) == '\0')
279 else
280 {
282 COPYCHAR(curpos, state->prsbuf);
283 curpos += pg_mblen(state->prsbuf);
284 }
285 }
286 else if (statecode == WAITCHARCMPLX)
287 {
288 if (!state->is_web && t_iseq(state->prsbuf, '\''))
289 {
291 COPYCHAR(curpos, state->prsbuf);
292 curpos += pg_mblen(state->prsbuf);
293 statecode = WAITENDCMPLX;
294 }
295 else
296 {
298 *(curpos) = '\0';
299 if (curpos == state->word)
301 if (state->oprisdelim)
302 {
303 /* state->prsbuf+=pg_mblen(state->prsbuf); */
305 }
306 else
307 statecode = WAITPOSINFO;
308 continue; /* recheck current character */
309 }
310 }
311 else if (statecode == WAITPOSINFO)
312 {
313 if (t_iseq(state->prsbuf, ':'))
314 statecode = INPOSINFO;
315 else
317 }
318 else if (statecode == INPOSINFO)
319 {
320 if (isdigit((unsigned char) *state->prsbuf))
321 {
322 if (posalen == 0)
323 {
324 posalen = 4;
325 pos = (WordEntryPos *) palloc(sizeof(WordEntryPos) * posalen);
326 npos = 0;
327 }
328 else if (npos + 1 >= posalen)
329 {
330 posalen *= 2;
331 pos = (WordEntryPos *) repalloc(pos, sizeof(WordEntryPos) * posalen);
332 }
333 npos++;
334 WEP_SETPOS(pos[npos - 1], LIMITPOS(atoi(state->prsbuf)));
335 /* we cannot get here in tsquery, so no need for 2 errmsgs */
336 if (WEP_GETPOS(pos[npos - 1]) == 0)
337 ereturn(state->escontext, false,
338 (errcode(ERRCODE_SYNTAX_ERROR),
339 errmsg("wrong position info in tsvector: \"%s\"",
340 state->bufstart)));
341 WEP_SETWEIGHT(pos[npos - 1], 0);
342 statecode = WAITPOSDELIM;
343 }
344 else
346 }
347 else if (statecode == WAITPOSDELIM)
348 {
349 if (t_iseq(state->prsbuf, ','))
350 statecode = INPOSINFO;
351 else if (t_iseq(state->prsbuf, 'a') || t_iseq(state->prsbuf, 'A') || t_iseq(state->prsbuf, '*'))
352 {
353 if (WEP_GETWEIGHT(pos[npos - 1]))
355 WEP_SETWEIGHT(pos[npos - 1], 3);
356 }
357 else if (t_iseq(state->prsbuf, 'b') || t_iseq(state->prsbuf, 'B'))
358 {
359 if (WEP_GETWEIGHT(pos[npos - 1]))
361 WEP_SETWEIGHT(pos[npos - 1], 2);
362 }
363 else if (t_iseq(state->prsbuf, 'c') || t_iseq(state->prsbuf, 'C'))
364 {
365 if (WEP_GETWEIGHT(pos[npos - 1]))
367 WEP_SETWEIGHT(pos[npos - 1], 1);
368 }
369 else if (t_iseq(state->prsbuf, 'd') || t_iseq(state->prsbuf, 'D'))
370 {
371 if (WEP_GETWEIGHT(pos[npos - 1]))
373 WEP_SETWEIGHT(pos[npos - 1], 0);
374 }
375 else if (isspace((unsigned char) *state->prsbuf) ||
376 *(state->prsbuf) == '\0')
378 else if (!isdigit((unsigned char) *state->prsbuf))
380 }
381 else /* internal error */
382 elog(ERROR, "unrecognized state in gettoken_tsvector: %d",
383 statecode);
384
385 /* get next char */
386 state->prsbuf += pg_mblen(state->prsbuf);
387 }
388}
int errcode(int sqlerrcode)
Definition: elog.c:853
#define ereturn(context, dummy_value,...)
Definition: elog.h:277
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
Assert(PointerIsAligned(start, uint64))
#define ISOPERATOR(x)
Definition: ltree.h:167
#define t_iseq(x, c)
Definition: ts_locale.h:38
#define COPYCHAR(d, s)
Definition: ts_locale.h:40
#define WEP_GETPOS(x)
Definition: ts_type.h:80
#define WEP_SETPOS(x, v)
Definition: ts_type.h:83
uint16 WordEntryPos
Definition: ts_type.h:63
#define WEP_SETWEIGHT(x, v)
Definition: ts_type.h:82
#define LIMITPOS(x)
Definition: ts_type.h:87
#define WEP_GETWEIGHT(x)
Definition: ts_type.h:79
#define WAITNEXTCHAR
#define PRSSYNTAXERROR
#define WAITENDCMPLX
#define WAITENDWORD
#define WAITCHARCMPLX
#define WAITPOSINFO
#define WAITWORD
#define INPOSINFO
#define RESIZEPRSBUF
#define RETURN_TOKEN
#define WAITPOSDELIM

References Assert(), COPYCHAR, elog, ereturn, errcode(), errmsg(), ERROR, INPOSINFO, ISOPERATOR, LIMITPOS, palloc(), pg_mblen(), PRSSYNTAXERROR, repalloc(), RESIZEPRSBUF, RETURN_TOKEN, t_iseq, WAITCHARCMPLX, WAITENDCMPLX, WAITENDWORD, WAITNEXTCHAR, WAITPOSDELIM, WAITPOSINFO, WAITWORD, WEP_GETPOS, WEP_GETWEIGHT, WEP_SETPOS, and WEP_SETWEIGHT.

Referenced by gettoken_query_standard(), gettoken_query_websearch(), and tsvectorin().

◆ hlparsetext()

void hlparsetext ( Oid  cfgId,
HeadlineParsedText prs,
TSQuery  query,
char *  buf,
int32  buflen 
)

◆ init_tsvector_parser()

TSVectorParseState init_tsvector_parser ( char *  input,
int  flags,
Node escontext 
)

Definition at line 57 of file tsvector_parser.c.

58{
60
62 state->prsbuf = input;
63 state->bufstart = input;
64 state->len = 32;
65 state->word = (char *) palloc(state->len);
67 state->oprisdelim = (flags & P_TSV_OPR_IS_DELIM) != 0;
68 state->is_tsquery = (flags & P_TSV_IS_TSQUERY) != 0;
69 state->is_web = (flags & P_TSV_IS_WEB) != 0;
70 state->escontext = escontext;
71
72 return state;
73}
FILE * input
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1546
#define P_TSV_IS_TSQUERY
Definition: ts_utils.h:30
struct TSVectorParseStateData * TSVectorParseState
Definition: ts_utils.h:26
#define P_TSV_IS_WEB
Definition: ts_utils.h:31
#define P_TSV_OPR_IS_DELIM
Definition: ts_utils.h:29

References input, P_TSV_IS_TSQUERY, P_TSV_IS_WEB, P_TSV_OPR_IS_DELIM, palloc(), and pg_database_encoding_max_length().

Referenced by parse_tsquery(), and tsvectorin().

◆ make_tsvector()

TSVector make_tsvector ( ParsedText prs)

Definition at line 165 of file to_tsany.c.

166{
167 int i,
168 j,
169 lenstr = 0,
170 totallen;
171 TSVector in;
172 WordEntry *ptr;
173 char *str;
174 int stroff;
175
176 /* Merge duplicate words */
177 if (prs->curwords > 0)
178 prs->curwords = uniqueWORD(prs->words, prs->curwords);
179
180 /* Determine space needed */
181 for (i = 0; i < prs->curwords; i++)
182 {
183 lenstr += prs->words[i].len;
184 if (prs->words[i].alen)
185 {
186 lenstr = SHORTALIGN(lenstr);
187 lenstr += sizeof(uint16) + prs->words[i].pos.apos[0] * sizeof(WordEntryPos);
188 }
189 }
190
191 if (lenstr > MAXSTRPOS)
193 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
194 errmsg("string is too long for tsvector (%d bytes, max %d bytes)", lenstr, MAXSTRPOS)));
195
196 totallen = CALCDATASIZE(prs->curwords, lenstr);
197 in = (TSVector) palloc0(totallen);
198 SET_VARSIZE(in, totallen);
199 in->size = prs->curwords;
200
201 ptr = ARRPTR(in);
202 str = STRPTR(in);
203 stroff = 0;
204 for (i = 0; i < prs->curwords; i++)
205 {
206 ptr->len = prs->words[i].len;
207 ptr->pos = stroff;
208 memcpy(str + stroff, prs->words[i].word, prs->words[i].len);
209 stroff += prs->words[i].len;
210 pfree(prs->words[i].word);
211 if (prs->words[i].alen)
212 {
213 int k = prs->words[i].pos.apos[0];
214 WordEntryPos *wptr;
215
216 if (k > 0xFFFF)
217 elog(ERROR, "positions array too long");
218
219 ptr->haspos = 1;
220 stroff = SHORTALIGN(stroff);
221 *(uint16 *) (str + stroff) = (uint16) k;
222 wptr = POSDATAPTR(in, ptr);
223 for (j = 0; j < k; j++)
224 {
225 WEP_SETWEIGHT(wptr[j], 0);
226 WEP_SETPOS(wptr[j], prs->words[i].pos.apos[j + 1]);
227 }
228 stroff += sizeof(uint16) + k * sizeof(WordEntryPos);
229 pfree(prs->words[i].pos.apos);
230 }
231 else
232 ptr->haspos = 0;
233 ptr++;
234 }
235
236 if (prs->words)
237 pfree(prs->words);
238
239 return in;
240}
#define SHORTALIGN(LEN)
Definition: c.h:778
uint16_t uint16
Definition: c.h:501
#define ARRPTR(x)
Definition: cube.c:25
const char * str
#define CALCDATASIZE(x, lenstr)
Definition: hstore.h:72
#define STRPTR(x)
Definition: hstore.h:76
int j
Definition: isn.c:75
void * palloc0(Size size)
Definition: mcxt.c:1347
int32 curwords
Definition: ts_utils.h:106
ParsedWord * words
Definition: ts_utils.h:104
uint16 alen
Definition: ts_utils.h:87
uint16 len
Definition: ts_utils.h:85
uint16 pos
Definition: ts_utils.h:90
char * word
Definition: ts_utils.h:99
int32 size
Definition: ts_type.h:93
uint32 pos
Definition: ts_type.h:46
uint32 haspos
Definition: ts_type.h:44
uint32 len
Definition: ts_type.h:45
static int uniqueWORD(ParsedWord *a, int32 l)
Definition: to_tsany.c:77
TSVectorData * TSVector
Definition: ts_type.h:98
#define POSDATAPTR(x, e)
Definition: ts_type.h:111
#define MAXSTRPOS
Definition: ts_type.h:50

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

Referenced by json_to_tsvector_worker(), jsonb_to_tsvector_worker(), to_tsvector_byid(), and tsvector_update_trigger().

◆ makeTSQuerySign()

TSQuerySign makeTSQuerySign ( TSQuery  a)

Definition at line 250 of file tsquery_op.c.

251{
252 int i;
253 QueryItem *ptr = GETQUERY(a);
254 TSQuerySign sign = 0;
255
256 for (i = 0; i < a->size; i++)
257 {
258 if (ptr->type == QI_VAL)
259 sign |= ((TSQuerySign) 1) << (((unsigned int) ptr->qoperand.valcrc) % TSQS_SIGLEN);
260 ptr++;
261 }
262
263 return sign;
264}
char sign
Definition: informix.c:693
int a
Definition: isn.c:70
int32 valcrc
Definition: ts_type.h:164
#define TSQS_SIGLEN
Definition: ts_utils.h:251
QueryOperand qoperand
Definition: ts_type.h:210
QueryItemType type
Definition: ts_type.h:208

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

Referenced by gtsquery_compress(), and gtsquery_consistent().

◆ parse_tsquery()

TSQuery parse_tsquery ( char *  buf,
PushFunction  pushval,
Datum  opaque,
int  flags,
Node escontext 
)

Definition at line 817 of file tsquery.c.

822{
824 int i;
825 TSQuery query;
826 int commonlen;
827 QueryItem *ptr;
828 ListCell *cell;
829 bool noisy;
830 bool needcleanup;
831 int tsv_flags = P_TSV_OPR_IS_DELIM | P_TSV_IS_TSQUERY;
832
833 /* plain should not be used with web */
834 Assert((flags & (P_TSQ_PLAIN | P_TSQ_WEB)) != (P_TSQ_PLAIN | P_TSQ_WEB));
835
836 /* select suitable tokenizer */
837 if (flags & P_TSQ_PLAIN)
838 state.gettoken = gettoken_query_plain;
839 else if (flags & P_TSQ_WEB)
840 {
842 tsv_flags |= P_TSV_IS_WEB;
843 }
844 else
846
847 /* emit nuisance NOTICEs only if not doing soft errors */
848 noisy = !(escontext && IsA(escontext, ErrorSaveContext));
849
850 /* init state */
851 state.buffer = buf;
852 state.buf = buf;
853 state.count = 0;
854 state.state = WAITFIRSTOPERAND;
855 state.polstr = NIL;
856 state.escontext = escontext;
857
858 /* init value parser's state */
859 state.valstate = init_tsvector_parser(state.buffer, tsv_flags, escontext);
860
861 /* init list of operand */
862 state.sumlen = 0;
863 state.lenop = 64;
864 state.curop = state.op = (char *) palloc(state.lenop);
865 *(state.curop) = '\0';
866
867 /* parse query & make polish notation (postfix, but in reverse order) */
868 makepol(&state, pushval, opaque);
869
871
873 return NULL;
874
875 if (state.polstr == NIL)
876 {
877 if (noisy)
879 (errmsg("text-search query doesn't contain lexemes: \"%s\"",
880 state.buffer)));
881 query = (TSQuery) palloc(HDRSIZETQ);
882 SET_VARSIZE(query, HDRSIZETQ);
883 query->size = 0;
884 return query;
885 }
886
887 if (TSQUERY_TOO_BIG(list_length(state.polstr), state.sumlen))
888 ereturn(escontext, NULL,
889 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
890 errmsg("tsquery is too large")));
891 commonlen = COMPUTESIZE(list_length(state.polstr), state.sumlen);
892
893 /* Pack the QueryItems in the final TSQuery struct to return to caller */
894 query = (TSQuery) palloc0(commonlen);
895 SET_VARSIZE(query, commonlen);
896 query->size = list_length(state.polstr);
897 ptr = GETQUERY(query);
898
899 /* Copy QueryItems to TSQuery */
900 i = 0;
901 foreach(cell, state.polstr)
902 {
903 QueryItem *item = (QueryItem *) lfirst(cell);
904
905 switch (item->type)
906 {
907 case QI_VAL:
908 memcpy(&ptr[i], item, sizeof(QueryOperand));
909 break;
910 case QI_VALSTOP:
911 ptr[i].type = QI_VALSTOP;
912 break;
913 case QI_OPR:
914 memcpy(&ptr[i], item, sizeof(QueryOperator));
915 break;
916 default:
917 elog(ERROR, "unrecognized QueryItem type: %d", item->type);
918 }
919 i++;
920 }
921
922 /* Copy all the operand strings to TSQuery */
923 memcpy(GETOPERAND(query), state.op, state.sumlen);
924 pfree(state.op);
925
926 /*
927 * Set left operand pointers for every operator. While we're at it,
928 * detect whether there are any QI_VALSTOP nodes.
929 */
930 findoprnd(ptr, query->size, &needcleanup);
931
932 /*
933 * If there are QI_VALSTOP nodes, delete them and simplify the tree.
934 */
935 if (needcleanup)
936 query = cleanup_tsquery_stopwords(query, noisy);
937
938 return query;
939}
#define SOFT_ERROR_OCCURRED(escontext)
Definition: miscnodes.h:53
#define IsA(nodeptr, _type_)
Definition: nodes.h:160
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
static char * buf
Definition: pg_test_fsync.c:72
TSQueryData * TSQuery
Definition: ts_type.h:225
#define QI_OPR
Definition: ts_type.h:150
#define TSQUERY_TOO_BIG(size, lenofoperand)
Definition: ts_type.h:233
#define QI_VALSTOP
Definition: ts_type.h:151
#define P_TSQ_PLAIN
Definition: ts_utils.h:64
#define P_TSQ_WEB
Definition: ts_utils.h:65
static ts_tokentype gettoken_query_standard(TSQueryParserState state, int8 *operator, int *lenval, char **strval, int16 *weight, bool *prefix)
Definition: tsquery.c:286
static void findoprnd(QueryItem *ptr, int size, bool *needcleanup)
Definition: tsquery.c:784
@ WAITFIRSTOPERAND
Definition: tsquery.c:44
static void makepol(TSQueryParserState state, PushFunction pushval, Datum opaque)
Definition: tsquery.c:672
static ts_tokentype gettoken_query_plain(TSQueryParserState state, int8 *operator, int *lenval, char **strval, int16 *weight, bool *prefix)
Definition: tsquery.c:510
static ts_tokentype gettoken_query_websearch(TSQueryParserState state, int8 *operator, int *lenval, char **strval, int16 *weight, bool *prefix)
Definition: tsquery.c:398
TSQuery cleanup_tsquery_stopwords(TSQuery in, bool noisy)
void close_tsvector_parser(TSVectorParseState state)
TSVectorParseState init_tsvector_parser(char *input, int flags, Node *escontext)

References Assert(), buf, cleanup_tsquery_stopwords(), close_tsvector_parser(), COMPUTESIZE, elog, ereport, ereturn, errcode(), errmsg(), ERROR, TSQueryParserStateData::escontext, findoprnd(), GETOPERAND, GETQUERY, gettoken_query_plain(), gettoken_query_standard(), gettoken_query_websearch(), HDRSIZETQ, i, init_tsvector_parser(), IsA, lfirst, list_length(), makepol(), NIL, NOTICE, P_TSQ_PLAIN, P_TSQ_WEB, P_TSV_IS_TSQUERY, P_TSV_IS_WEB, P_TSV_OPR_IS_DELIM, palloc(), palloc0(), pfree(), QI_OPR, QI_VAL, QI_VALSTOP, SET_VARSIZE, TSQueryData::size, SOFT_ERROR_OCCURRED, TSQUERY_TOO_BIG, QueryItem::type, and WAITFIRSTOPERAND.

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

◆ parsetext()

void parsetext ( Oid  cfgId,
ParsedText prs,
char *  buf,
int32  buflen 
)

◆ pushOperator()

void pushOperator ( TSQueryParserState  state,
int8  oper,
int16  distance 
)

Definition at line 531 of file tsquery.c.

532{
533 QueryOperator *tmp;
534
535 Assert(oper == OP_NOT || oper == OP_AND || oper == OP_OR || oper == OP_PHRASE);
536
537 tmp = (QueryOperator *) palloc0(sizeof(QueryOperator));
538 tmp->type = QI_OPR;
539 tmp->oper = oper;
540 tmp->distance = (oper == OP_PHRASE) ? distance : 0;
541 /* left is filled in later with findoprnd */
542
543 state->polstr = lcons(tmp, state->polstr);
544}
List * lcons(void *datum, List *list)
Definition: list.c:495
Operator oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId, bool noError, int location)
Definition: parse_oper.c:370
int16 distance
Definition: ts_type.h:196
QueryItemType type
Definition: ts_type.h:194
#define OP_AND
Definition: ts_type.h:180
#define OP_PHRASE
Definition: ts_type.h:182
#define OP_OR
Definition: ts_type.h:181
#define OP_NOT
Definition: ts_type.h:179

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

Referenced by cleanOpStack(), and pushval_morph().

◆ pushStop()

void pushStop ( TSQueryParserState  state)

Definition at line 616 of file tsquery.c.

617{
618 QueryOperand *tmp;
619
620 tmp = (QueryOperand *) palloc0(sizeof(QueryOperand));
621 tmp->type = QI_VALSTOP;
622
623 state->polstr = lcons(tmp, state->polstr);
624}

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

Referenced by gettoken_query_websearch(), and pushval_morph().

◆ pushValue()

void pushValue ( TSQueryParserState  state,
char *  strval,
int  lenval,
int16  weight,
bool  prefix 
)

Definition at line 580 of file tsquery.c.

581{
582 pg_crc32 valcrc;
583
584 if (lenval >= MAXSTRLEN)
585 ereturn(state->escontext,,
586 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
587 errmsg("word is too long in tsquery: \"%s\"",
588 state->buffer)));
589
590 INIT_LEGACY_CRC32(valcrc);
591 COMP_LEGACY_CRC32(valcrc, strval, lenval);
592 FIN_LEGACY_CRC32(valcrc);
593 pushValue_internal(state, valcrc, state->curop - state->op, lenval, weight, prefix);
594
595 /* append the value string to state.op, enlarging buffer if needed first */
596 while (state->curop - state->op + lenval + 1 >= state->lenop)
597 {
598 int used = state->curop - state->op;
599
600 state->lenop *= 2;
601 state->op = (char *) repalloc(state->op, state->lenop);
602 state->curop = state->op + used;
603 }
604 memcpy(state->curop, strval, lenval);
605 state->curop += lenval;
606 *(state->curop) = '\0';
607 state->curop++;
608 state->sumlen += lenval + 1 /* \0 */ ;
609}
uint32 pg_crc32
Definition: pg_crc.h:37
#define INIT_LEGACY_CRC32(crc)
Definition: pg_crc.h:79
#define COMP_LEGACY_CRC32(crc, data, len)
Definition: pg_crc.h:81
#define FIN_LEGACY_CRC32(crc)
Definition: pg_crc.h:80
#define MAXSTRLEN
Definition: ts_type.h:49
static void pushValue_internal(TSQueryParserState state, pg_crc32 valcrc, int distance, int lenval, int weight, bool prefix)
Definition: tsquery.c:547

References COMP_LEGACY_CRC32, ereturn, errcode(), errmsg(), FIN_LEGACY_CRC32, INIT_LEGACY_CRC32, MAXSTRLEN, pushValue_internal(), and repalloc().

Referenced by pushval_asis(), and pushval_morph().

◆ QT2QTN()

QTNode * QT2QTN ( QueryItem in,
char *  operand 
)

Definition at line 25 of file tsquery_util.c.

26{
27 QTNode *node = (QTNode *) palloc0(sizeof(QTNode));
28
29 /* since this function recurses, it could be driven to stack overflow. */
31
32 node->valnode = in;
33
34 if (in->type == QI_OPR)
35 {
36 node->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);
37 node->child[0] = QT2QTN(in + 1, operand);
38 node->sign = node->child[0]->sign;
39 if (in->qoperator.oper == OP_NOT)
40 node->nchild = 1;
41 else
42 {
43 node->nchild = 2;
44 node->child[1] = QT2QTN(in + in->qoperator.left, operand);
45 node->sign |= node->child[1]->sign;
46 }
47 }
48 else if (operand)
49 {
50 node->word = operand + in->qoperand.distance;
51 node->sign = ((uint32) 1) << (((unsigned int) in->qoperand.valcrc) % 32);
52 }
53
54 return node;
55}
uint32_t uint32
Definition: c.h:502
void check_stack_depth(void)
Definition: stack_depth.c:95
int32 nchild
Definition: ts_utils.h:238
QueryItem * valnode
Definition: ts_utils.h:236
uint32 sign
Definition: ts_utils.h:240
char * word
Definition: ts_utils.h:239
struct QTNode ** child
Definition: ts_utils.h:241
uint32 left
Definition: ts_type.h:197
QTNode * QT2QTN(QueryItem *in, char *operand)
Definition: tsquery_util.c:25
QueryOperator qoperator
Definition: ts_type.h:209

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().

◆ QTN2QT()

TSQuery QTN2QT ( QTNode in)

Definition at line 363 of file tsquery_util.c.

364{
365 TSQuery out;
366 int len;
367 int sumlen = 0,
368 nnode = 0;
370
371 cntsize(in, &sumlen, &nnode);
372
373 if (TSQUERY_TOO_BIG(nnode, sumlen))
375 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
376 errmsg("tsquery is too large")));
377 len = COMPUTESIZE(nnode, sumlen);
378
379 out = (TSQuery) palloc0(len);
380 SET_VARSIZE(out, len);
381 out->size = nnode;
382
383 state.curitem = GETQUERY(out);
384 state.operand = state.curoperand = GETOPERAND(out);
385
386 fillQT(&state, in);
387 return out;
388}
static void cntsize(QTNode *in, int *sumlen, int *nnode)
Definition: tsquery_util.c:292
static void fillQT(QTN2QTState *state, QTNode *in)
Definition: tsquery_util.c:323

References cntsize(), COMPUTESIZE, ereport, errcode(), errmsg(), ERROR, fillQT(), GETOPERAND, GETQUERY, len, 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().

◆ QTNBinary()

void QTNBinary ( QTNode in)

Definition at line 250 of file tsquery_util.c.

251{
252 int i;
253
254 /* since this function recurses, it could be driven to stack overflow. */
256
257 if (in->valnode->type != QI_OPR)
258 return;
259
260 for (i = 0; i < in->nchild; i++)
261 QTNBinary(in->child[i]);
262
263 while (in->nchild > 2)
264 {
265 QTNode *nn = (QTNode *) palloc0(sizeof(QTNode));
266
267 nn->valnode = (QueryItem *) palloc0(sizeof(QueryItem));
268 nn->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);
269
270 nn->nchild = 2;
271 nn->flags = QTN_NEEDFREE;
272
273 nn->child[0] = in->child[0];
274 nn->child[1] = in->child[1];
275 nn->sign = nn->child[0]->sign | nn->child[1]->sign;
276
277 nn->valnode->type = in->valnode->type;
279
280 in->child[0] = nn;
281 in->child[1] = in->child[in->nchild - 1];
282 in->nchild--;
283 }
284}
uint32 flags
Definition: ts_utils.h:237
#define QTN_NEEDFREE
Definition: ts_utils.h:245
void QTNBinary(QTNode *in)
Definition: tsquery_util.c:250

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().

◆ QTNClearFlags()

void QTNClearFlags ( QTNode in,
uint32  flags 
)

Definition at line 434 of file tsquery_util.c.

435{
436 /* since this function recurses, it could be driven to stack overflow. */
438
439 in->flags &= ~flags;
440
441 if (in->valnode->type != QI_VAL)
442 {
443 int i;
444
445 for (i = 0; i < in->nchild; i++)
446 QTNClearFlags(in->child[i], flags);
447 }
448}
void QTNClearFlags(QTNode *in, uint32 flags)
Definition: tsquery_util.c:434

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().

◆ QTNCopy()

QTNode * QTNCopy ( QTNode in)

Definition at line 396 of file tsquery_util.c.

397{
398 QTNode *out;
399
400 /* since this function recurses, it could be driven to stack overflow. */
402
403 out = (QTNode *) palloc(sizeof(QTNode));
404
405 *out = *in;
406 out->valnode = (QueryItem *) palloc(sizeof(QueryItem));
407 *(out->valnode) = *(in->valnode);
408 out->flags |= QTN_NEEDFREE;
409
410 if (in->valnode->type == QI_VAL)
411 {
412 out->word = palloc(in->valnode->qoperand.length + 1);
413 memcpy(out->word, in->word, in->valnode->qoperand.length);
414 out->word[in->valnode->qoperand.length] = '\0';
415 out->flags |= QTN_WORDFREE;
416 }
417 else
418 {
419 int i;
420
421 out->child = (QTNode **) palloc(sizeof(QTNode *) * in->nchild);
422
423 for (i = 0; i < in->nchild; i++)
424 out->child[i] = QTNCopy(in->child[i]);
425 }
426
427 return out;
428}
#define QTN_WORDFREE
Definition: ts_utils.h:247
QTNode * QTNCopy(QTNode *in)
Definition: tsquery_util.c:396

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().

◆ QTNEq()

bool QTNEq ( QTNode a,
QTNode b 
)

Definition at line 183 of file tsquery_util.c.

184{
185 uint32 sign = a->sign & b->sign;
186
187 if (!(sign == a->sign && sign == b->sign))
188 return false;
189
190 return (QTNodeCompare(a, b) == 0);
191}
int b
Definition: isn.c:71
int QTNodeCompare(QTNode *an, QTNode *bn)
Definition: tsquery_util.c:97

References a, b, QTNodeCompare(), and sign.

Referenced by findeq().

◆ QTNFree()

void QTNFree ( QTNode in)

Definition at line 64 of file tsquery_util.c.

65{
66 if (!in)
67 return;
68
69 /* since this function recurses, it could be driven to stack overflow. */
71
72 if (in->valnode->type == QI_VAL && in->word && (in->flags & QTN_WORDFREE) != 0)
73 pfree(in->word);
74
75 if (in->valnode->type == QI_OPR)
76 {
77 int i;
78
79 for (i = 0; i < in->nchild; i++)
80 QTNFree(in->child[i]);
81 }
82 if (in->child)
83 pfree(in->child);
84
85 if (in->flags & QTN_NEEDFREE)
86 pfree(in->valnode);
87
88 pfree(in);
89}
void QTNFree(QTNode *in)
Definition: tsquery_util.c:64

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().

◆ QTNodeCompare()

int QTNodeCompare ( QTNode an,
QTNode bn 
)

Definition at line 97 of file tsquery_util.c.

98{
99 /* since this function recurses, it could be driven to stack overflow. */
101
102 if (an->valnode->type != bn->valnode->type)
103 return (an->valnode->type > bn->valnode->type) ? -1 : 1;
104
105 if (an->valnode->type == QI_OPR)
106 {
107 QueryOperator *ao = &an->valnode->qoperator;
108 QueryOperator *bo = &bn->valnode->qoperator;
109
110 if (ao->oper != bo->oper)
111 return (ao->oper > bo->oper) ? -1 : 1;
112
113 if (an->nchild != bn->nchild)
114 return (an->nchild > bn->nchild) ? -1 : 1;
115
116 {
117 int i,
118 res;
119
120 for (i = 0; i < an->nchild; i++)
121 if ((res = QTNodeCompare(an->child[i], bn->child[i])) != 0)
122 return res;
123 }
124
125 if (ao->oper == OP_PHRASE && ao->distance != bo->distance)
126 return (ao->distance > bo->distance) ? -1 : 1;
127
128 return 0;
129 }
130 else if (an->valnode->type == QI_VAL)
131 {
132 QueryOperand *ao = &an->valnode->qoperand;
133 QueryOperand *bo = &bn->valnode->qoperand;
134
135 if (ao->valcrc != bo->valcrc)
136 {
137 return (ao->valcrc > bo->valcrc) ? -1 : 1;
138 }
139
140 return tsCompareString(an->word, ao->length, bn->word, bo->length, false);
141 }
142 else
143 {
144 elog(ERROR, "unrecognized QueryItem type: %d", an->valnode->type);
145 return 0; /* keep compiler quiet */
146 }
147}
int32 tsCompareString(char *a, int lena, char *b, int lenb, bool prefix)
Definition: tsvector_op.c:1152

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().

◆ QTNSort()

void QTNSort ( QTNode in)

Definition at line 163 of file tsquery_util.c.

164{
165 int i;
166
167 /* since this function recurses, it could be driven to stack overflow. */
169
170 if (in->valnode->type != QI_OPR)
171 return;
172
173 for (i = 0; i < in->nchild; i++)
174 QTNSort(in->child[i]);
175 if (in->nchild > 1 && in->valnode->qoperator.oper != OP_PHRASE)
176 qsort(in->child, in->nchild, sizeof(QTNode *), cmpQTN);
177}
#define qsort(a, b, c, d)
Definition: port.h:475
void QTNSort(QTNode *in)
Definition: tsquery_util.c:163
static int cmpQTN(const void *a, const void *b)
Definition: tsquery_util.c:153

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().

◆ QTNTernary()

void QTNTernary ( QTNode in)

Definition at line 201 of file tsquery_util.c.

202{
203 int i;
204
205 /* since this function recurses, it could be driven to stack overflow. */
207
208 if (in->valnode->type != QI_OPR)
209 return;
210
211 for (i = 0; i < in->nchild; i++)
212 QTNTernary(in->child[i]);
213
214 /* Only AND and OR are associative, so don't flatten other node types */
215 if (in->valnode->qoperator.oper != OP_AND &&
216 in->valnode->qoperator.oper != OP_OR)
217 return;
218
219 for (i = 0; i < in->nchild; i++)
220 {
221 QTNode *cc = in->child[i];
222
223 if (cc->valnode->type == QI_OPR &&
225 {
226 int oldnchild = in->nchild;
227
228 in->nchild += cc->nchild - 1;
229 in->child = (QTNode **) repalloc(in->child, in->nchild * sizeof(QTNode *));
230
231 if (i + 1 != oldnchild)
232 memmove(in->child + i + cc->nchild, in->child + i + 1,
233 (oldnchild - i - 1) * sizeof(QTNode *));
234
235 memcpy(in->child + i, cc->child, cc->nchild * sizeof(QTNode *));
236 i += cc->nchild - 1;
237
238 if (cc->flags & QTN_NEEDFREE)
239 pfree(cc->valnode);
240 pfree(cc);
241 }
242 }
243}
void QTNTernary(QTNode *in)
Definition: tsquery_util.c:201

References check_stack_depth(), QTNode::child, QTNode::flags, i, 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().

◆ reset_tsvector_parser()

void reset_tsvector_parser ( TSVectorParseState  state,
char *  input 
)

Definition at line 81 of file tsvector_parser.c.

82{
83 state->prsbuf = input;
84}

References input.

Referenced by gettoken_query_standard(), and gettoken_query_websearch().

◆ TS_execute()

bool TS_execute ( QueryItem curitem,
void *  arg,
uint32  flags,
TSExecuteCallback  chkcond 
)

Definition at line 1854 of file tsvector_op.c.

1856{
1857 /*
1858 * If we get TS_MAYBE from the recursion, return true. We could only see
1859 * that result if the caller passed TS_EXEC_PHRASE_NO_POS, so there's no
1860 * need to check again.
1861 */
1862 return TS_execute_recurse(curitem, arg, flags, chkcond) != TS_NO;
1863}
void * arg
static TSTernaryValue TS_execute_recurse(QueryItem *curitem, void *arg, uint32 flags, TSExecuteCallback chkcond)
Definition: tsvector_op.c:1883

References arg, TS_execute_recurse(), and TS_NO.

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

◆ TS_execute_locations()

List * TS_execute_locations ( QueryItem curitem,
void *  arg,
uint32  flags,
TSExecuteCallback  chkcond 
)

Definition at line 2007 of file tsvector_op.c.

2010{
2011 List *result;
2012
2013 /* No flags supported, as yet */
2014 Assert(flags == TS_EXEC_EMPTY);
2015 if (TS_execute_locations_recurse(curitem, arg, chkcond, &result))
2016 return result;
2017 return NIL;
2018}
Definition: pg_list.h:54
#define TS_EXEC_EMPTY
Definition: ts_utils.h:188
static bool TS_execute_locations_recurse(QueryItem *curitem, void *arg, TSExecuteCallback chkcond, List **locations)
Definition: tsvector_op.c:2025

References arg, Assert(), NIL, TS_EXEC_EMPTY, and TS_execute_locations_recurse().

Referenced by prsd_headline().

◆ TS_execute_ternary()

TSTernaryValue TS_execute_ternary ( QueryItem curitem,
void *  arg,
uint32  flags,
TSExecuteCallback  chkcond 
)

Definition at line 1871 of file tsvector_op.c.

1873{
1874 return TS_execute_recurse(curitem, arg, flags, chkcond);
1875}

References arg, and TS_execute_recurse().

Referenced by gin_tsquery_consistent(), and gin_tsquery_triconsistent().

◆ tsCompareString()

int32 tsCompareString ( char *  a,
int  lena,
char *  b,
int  lenb,
bool  prefix 
)

Definition at line 1152 of file tsvector_op.c.

1153{
1154 int cmp;
1155
1156 if (lena == 0)
1157 {
1158 if (prefix)
1159 cmp = 0; /* empty string is prefix of anything */
1160 else
1161 cmp = (lenb > 0) ? -1 : 0;
1162 }
1163 else if (lenb == 0)
1164 {
1165 cmp = (lena > 0) ? 1 : 0;
1166 }
1167 else
1168 {
1169 cmp = memcmp(a, b, Min((unsigned int) lena, (unsigned int) lenb));
1170
1171 if (prefix)
1172 {
1173 if (cmp == 0 && lena > lenb)
1174 cmp = 1; /* a is longer, so not a prefix of b */
1175 }
1176 else if (cmp == 0 && lena != lenb)
1177 {
1178 cmp = (lena < lenb) ? -1 : 1;
1179 }
1180 }
1181
1182 return cmp;
1183}
#define Min(x, y)
Definition: c.h:975
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:743

References a, b, 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().

◆ tsquery_requires_match()

bool tsquery_requires_match ( QueryItem curitem)

Definition at line 2156 of file tsvector_op.c.

2157{
2158 /* since this function recurses, it could be driven to stack overflow */
2160
2161 if (curitem->type == QI_VAL)
2162 return true;
2163
2164 switch (curitem->qoperator.oper)
2165 {
2166 case OP_NOT:
2167
2168 /*
2169 * Assume there are no required matches underneath a NOT. For
2170 * some cases with nested NOTs, we could prove there's a required
2171 * match, but it seems unlikely to be worth the trouble.
2172 */
2173 return false;
2174
2175 case OP_PHRASE:
2176
2177 /*
2178 * Treat OP_PHRASE as OP_AND here
2179 */
2180 case OP_AND:
2181 /* If either side requires a match, we're good */
2182 if (tsquery_requires_match(curitem + curitem->qoperator.left))
2183 return true;
2184 else
2185 return tsquery_requires_match(curitem + 1);
2186
2187 case OP_OR:
2188 /* Both sides must require a match */
2189 if (tsquery_requires_match(curitem + curitem->qoperator.left))
2190 return tsquery_requires_match(curitem + 1);
2191 else
2192 return false;
2193
2194 default:
2195 elog(ERROR, "unrecognized operator: %d", curitem->qoperator.oper);
2196 }
2197
2198 /* not reachable, but keep compiler quiet */
2199 return false;
2200}
bool tsquery_requires_match(QueryItem *curitem)
Definition: tsvector_op.c:2156

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().

◆ TSQuerySignGetDatum()

static Datum TSQuerySignGetDatum ( TSQuerySign  X)
inlinestatic

Definition at line 254 of file ts_utils.h.

255{
256 return Int64GetDatum((int64) X);
257}
int64_t int64
Definition: c.h:499
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1807

References Int64GetDatum().

Referenced by gtsquery_compress(), and gtsquery_picksplit().