Coverage Report

Created: 2026-10-16 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/postgres/src/include/tsearch/ts_utils.h
Line
Count
Source
1
/*-------------------------------------------------------------------------
2
 *
3
 * ts_utils.h
4
 *    helper utilities for tsearch
5
 *
6
 * Copyright (c) 1998-2026, PostgreSQL Global Development Group
7
 *
8
 * src/include/tsearch/ts_utils.h
9
 *
10
 *-------------------------------------------------------------------------
11
 */
12
#ifndef _PG_TS_UTILS_H_
13
#define _PG_TS_UTILS_H_
14
15
#include "nodes/pg_list.h"
16
#include "tsearch/ts_public.h"
17
#include "tsearch/ts_type.h"
18
19
/*
20
 * Common parse definitions for tsvector and tsquery
21
 */
22
23
/* tsvector parser support. */
24
25
struct TSVectorParseStateData;  /* opaque struct in tsvector_parser.c */
26
typedef struct TSVectorParseStateData *TSVectorParseState;
27
28
/* flag bits that can be passed to init_tsvector_parser: */
29
0
#define P_TSV_OPR_IS_DELIM  (1 << 0)
30
0
#define P_TSV_IS_TSQUERY  (1 << 1)
31
0
#define P_TSV_IS_WEB    (1 << 2)
32
33
extern TSVectorParseState init_tsvector_parser(char *input, int flags,
34
                         Node *escontext);
35
extern void reset_tsvector_parser(TSVectorParseState state, char *input);
36
extern bool gettoken_tsvector(TSVectorParseState state,
37
                char **strval, int *lenval,
38
                WordEntryPos **pos_ptr, int *poslen,
39
                char **endptr);
40
extern void close_tsvector_parser(TSVectorParseState state);
41
42
/* phrase operator begins with '<' */
43
0
#define ISOPERATOR(x)   (*(x) == '!' || \
44
0
               *(x) == '&' || \
45
0
               *(x) == '|' || \
46
0
               *(x) == '(' || \
47
0
               *(x) == ')' || \
48
0
               *(x) == '<')
49
50
/* parse_tsquery */
51
52
struct TSQueryParserStateData;  /* private in backend/utils/adt/tsquery.c */
53
typedef struct TSQueryParserStateData *TSQueryParserState;
54
55
typedef void (*PushFunction) (void *opaque, TSQueryParserState state,
56
                char *token, int tokenlen,
57
                int16 tokenweights, /* bitmap as described in
58
                           * QueryOperand struct */
59
                bool prefix);
60
61
/* flag bits that can be passed to parse_tsquery: */
62
0
#define P_TSQ_PLAIN   (1 << 0)
63
0
#define P_TSQ_WEB   (1 << 1)
64
65
extern TSQuery parse_tsquery(char *buf,
66
               PushFunction pushval,
67
               void *opaque,
68
               int flags,
69
               Node *escontext);
70
71
/* Functions for use by PushFunction implementations */
72
extern void pushValue(TSQueryParserState state,
73
            char *strval, int lenval, int16 weight, bool prefix);
74
extern void pushStop(TSQueryParserState state);
75
extern void pushOperator(TSQueryParserState state, int8 oper, int16 distance);
76
77
/*
78
 * parse plain text and lexize words
79
 */
80
typedef struct
81
{
82
  uint16    flags;      /* currently, only TSL_PREFIX */
83
  uint16    len;
84
  uint16    nvariant;
85
  uint16    alen;
86
  union
87
  {
88
    uint16    pos;
89
90
    /*
91
     * When apos array is used, apos[0] is the number of elements in the
92
     * array (excluding apos[0]), and alen is the allocated size of the
93
     * array.  We do not allow more than MAXNUMPOS array elements.
94
     */
95
    uint16     *apos;
96
  }     pos;
97
  char     *word;
98
} ParsedWord;
99
100
typedef struct
101
{
102
  ParsedWord *words;
103
  int32   lenwords;
104
  int32   curwords;
105
  int32   pos;
106
} ParsedText;
107
108
extern void parsetext(Oid cfgId, ParsedText *prs, char *buf, int32 buflen);
109
110
/*
111
 * headline framework, flow in common to generate:
112
 *  1 parse text with hlparsetext
113
 *  2 parser-specific function to find part
114
 *  3 generateHeadline to generate result text
115
 */
116
117
extern void hlparsetext(Oid cfgId, HeadlineParsedText *prs, TSQuery query,
118
            char *buf, int32 buflen);
119
extern text *generateHeadline(HeadlineParsedText *prs);
120
121
/*
122
 * TSQuery execution support
123
 *
124
 * TS_execute() executes a tsquery against data that can be represented in
125
 * various forms.  The TSExecuteCallback callback function is called to check
126
 * whether a given primitive tsquery value is matched in the data.
127
 */
128
129
/* TS_execute requires ternary logic to handle NOT with phrase matches */
130
typedef enum
131
{
132
  TS_NO,            /* definitely no match */
133
  TS_YES,           /* definitely does match */
134
  TS_MAYBE,         /* can't verify match for lack of pos data */
135
} TSTernaryValue;
136
137
/*
138
 * struct ExecPhraseData is passed to a TSExecuteCallback function if we need
139
 * lexeme position data (because of a phrase-match operator in the tsquery).
140
 * The callback should fill in position data when it returns TS_YES (success).
141
 * If it cannot return position data, it should leave "data" unchanged and
142
 * return TS_MAYBE.  The caller of TS_execute() must then arrange for a later
143
 * recheck with position data available.
144
 *
145
 * The reported lexeme positions must be sorted and unique.  Callers must only
146
 * consult the position bits of the pos array, ie, WEP_GETPOS(data->pos[i]).
147
 * This allows the returned "pos" to point directly to the WordEntryPos
148
 * portion of a tsvector value.  If "allocated" is true then the pos array
149
 * is palloc'd workspace and caller may free it when done.
150
 *
151
 * "negate" means that the pos array contains positions where the query does
152
 * not match, rather than positions where it does.  "width" is positive when
153
 * the match is wider than one lexeme.  Neither of these fields normally need
154
 * to be touched by TSExecuteCallback functions; they are used for
155
 * phrase-search processing within TS_execute.
156
 *
157
 * All fields of the ExecPhraseData struct are initially zeroed by caller.
158
 */
159
typedef struct ExecPhraseData
160
{
161
  int     npos;     /* number of positions reported */
162
  bool    allocated;    /* pos points to palloc'd data? */
163
  bool    negate;     /* positions are where query is NOT matched */
164
  WordEntryPos *pos;      /* ordered, non-duplicate lexeme positions */
165
  int     width;      /* width of match in lexemes, less 1 */
166
} ExecPhraseData;
167
168
/*
169
 * Signature for TSQuery lexeme check functions
170
 *
171
 * arg: opaque value passed through from caller of TS_execute
172
 * val: lexeme to test for presence of
173
 * data: to be filled with lexeme positions; NULL if position data not needed
174
 *
175
 * Return TS_YES if lexeme is present in data, TS_MAYBE if it might be
176
 * present, TS_NO if it definitely is not present.  If data is not NULL,
177
 * it must be filled with lexeme positions if available.  If position data
178
 * is not available, leave *data as zeroes and return TS_MAYBE, never TS_YES.
179
 */
180
typedef TSTernaryValue (*TSExecuteCallback) (void *arg, QueryOperand *val,
181
                       ExecPhraseData *data);
182
183
/*
184
 * Flag bits for TS_execute
185
 */
186
0
#define TS_EXEC_EMPTY     (0x00)
187
/*
188
 * If TS_EXEC_SKIP_NOT is set, then NOT sub-expressions are automatically
189
 * evaluated to be true.  This was formerly the default behavior.  It's now
190
 * deprecated because it tends to give silly answers, but some applications
191
 * might still have a use for it.
192
 */
193
0
#define TS_EXEC_SKIP_NOT    (0x01)
194
/*
195
 * If TS_EXEC_PHRASE_NO_POS is set, allow OP_PHRASE to be executed lossily
196
 * in the absence of position information: a true result indicates that the
197
 * phrase might be present.  Without this flag, OP_PHRASE always returns
198
 * false if lexeme position information is not available.
199
 */
200
0
#define TS_EXEC_PHRASE_NO_POS (0x02)
201
202
extern bool TS_execute(QueryItem *curitem, void *arg, uint32 flags,
203
             TSExecuteCallback chkcond);
204
extern TSTernaryValue TS_execute_ternary(QueryItem *curitem, void *arg,
205
                     uint32 flags,
206
                     TSExecuteCallback chkcond);
207
extern List *TS_execute_locations(QueryItem *curitem, void *arg,
208
                  uint32 flags,
209
                  TSExecuteCallback chkcond);
210
extern bool tsquery_requires_match(QueryItem *curitem);
211
212
/*
213
 * to_ts* - text transformation to tsvector, tsquery
214
 */
215
extern TSVector make_tsvector(ParsedText *prs);
216
extern int32 tsCompareString(char *a, int lena, char *b, int lenb, bool prefix);
217
218
/*
219
 * Possible strategy numbers for indexes
220
 *    TSearchStrategyNumber  - (tsvector|text) @@ tsquery
221
 *    TSearchWithClassStrategyNumber  - tsvector @@@ tsquery
222
 */
223
#define TSearchStrategyNumber     1
224
#define TSearchWithClassStrategyNumber  2
225
226
/*
227
 * TSQuery Utilities
228
 */
229
extern QueryItem *clean_NOT(QueryItem *ptr, int32 *len);
230
extern TSQuery cleanup_tsquery_stopwords(TSQuery in, bool noisy);
231
232
typedef struct QTNode
233
{
234
  QueryItem  *valnode;
235
  uint32    flags;
236
  int32   nchild;
237
  char     *word;
238
  uint32    sign;
239
  struct QTNode **child;
240
} QTNode;
241
242
/* bits in QTNode.flags */
243
0
#define QTN_NEEDFREE  0x01
244
0
#define QTN_NOCHANGE  0x02
245
0
#define QTN_WORDFREE  0x04
246
247
typedef uint64 TSQuerySign;
248
249
0
#define TSQS_SIGLEN  (sizeof(TSQuerySign)*BITS_PER_BYTE)
250
251
static inline Datum
252
TSQuerySignGetDatum(TSQuerySign X)
253
0
{
254
0
  return Int64GetDatum((int64) X);
255
0
}
Unexecuted instantiation: to_tsany.c:TSQuerySignGetDatum
Unexecuted instantiation: ts_parse.c:TSQuerySignGetDatum
Unexecuted instantiation: wparser.c:TSQuerySignGetDatum
Unexecuted instantiation: wparser_def.c:TSQuerySignGetDatum
Unexecuted instantiation: tsginidx.c:TSQuerySignGetDatum
Unexecuted instantiation: tsgistidx.c:TSQuerySignGetDatum
Unexecuted instantiation: tsquery.c:TSQuerySignGetDatum
Unexecuted instantiation: tsquery_cleanup.c:TSQuerySignGetDatum
Unexecuted instantiation: tsquery_gist.c:TSQuerySignGetDatum
Unexecuted instantiation: tsquery_op.c:TSQuerySignGetDatum
Unexecuted instantiation: tsquery_rewrite.c:TSQuerySignGetDatum
Unexecuted instantiation: tsquery_util.c:TSQuerySignGetDatum
Unexecuted instantiation: tsrank.c:TSQuerySignGetDatum
Unexecuted instantiation: tsvector.c:TSQuerySignGetDatum
Unexecuted instantiation: tsvector_op.c:TSQuerySignGetDatum
Unexecuted instantiation: tsvector_parser.c:TSQuerySignGetDatum
256
257
static inline TSQuerySign
258
DatumGetTSQuerySign(Datum X)
259
0
{
260
0
  return (TSQuerySign) DatumGetInt64(X);
261
0
}
Unexecuted instantiation: to_tsany.c:DatumGetTSQuerySign
Unexecuted instantiation: ts_parse.c:DatumGetTSQuerySign
Unexecuted instantiation: wparser.c:DatumGetTSQuerySign
Unexecuted instantiation: wparser_def.c:DatumGetTSQuerySign
Unexecuted instantiation: tsginidx.c:DatumGetTSQuerySign
Unexecuted instantiation: tsgistidx.c:DatumGetTSQuerySign
Unexecuted instantiation: tsquery.c:DatumGetTSQuerySign
Unexecuted instantiation: tsquery_cleanup.c:DatumGetTSQuerySign
Unexecuted instantiation: tsquery_gist.c:DatumGetTSQuerySign
Unexecuted instantiation: tsquery_op.c:DatumGetTSQuerySign
Unexecuted instantiation: tsquery_rewrite.c:DatumGetTSQuerySign
Unexecuted instantiation: tsquery_util.c:DatumGetTSQuerySign
Unexecuted instantiation: tsrank.c:DatumGetTSQuerySign
Unexecuted instantiation: tsvector.c:DatumGetTSQuerySign
Unexecuted instantiation: tsvector_op.c:DatumGetTSQuerySign
Unexecuted instantiation: tsvector_parser.c:DatumGetTSQuerySign
262
263
0
#define PG_RETURN_TSQUERYSIGN(X)  return TSQuerySignGetDatum(X)
264
0
#define PG_GETARG_TSQUERYSIGN(n)  DatumGetTSQuerySign(PG_GETARG_DATUM(n))
265
266
267
extern QTNode *QT2QTN(QueryItem *in, char *operand);
268
extern TSQuery QTN2QT(QTNode *in);
269
extern void QTNFree(QTNode *in);
270
extern void QTNSort(QTNode *in);
271
extern void QTNTernary(QTNode *in);
272
extern void QTNBinary(QTNode *in);
273
extern int  QTNodeCompare(QTNode *an, QTNode *bn);
274
extern QTNode *QTNCopy(QTNode *in);
275
extern void QTNClearFlags(QTNode *in, uint32 flags);
276
extern bool QTNEq(QTNode *a, QTNode *b);
277
extern TSQuerySign makeTSQuerySign(TSQuery a);
278
extern QTNode *findsubquery(QTNode *root, QTNode *ex, QTNode *subs,
279
              bool *isfind);
280
281
#endif              /* _PG_TS_UTILS_H_ */