PostgreSQL Source Code  git master
tsquery_op.c File Reference
#include "postgres.h"
#include "lib/qunique.h"
#include "tsearch/ts_utils.h"
#include "utils/fmgrprotos.h"
#include "varatt.h"
Include dependency graph for tsquery_op.c:

Go to the source code of this file.

Macros

#define CMPFUNC(NAME, CONDITION)
 

Functions

Datum tsquery_numnode (PG_FUNCTION_ARGS)
 
static QTNodejoin_tsqueries (TSQuery a, TSQuery b, int8 operator, uint16 distance)
 
Datum tsquery_and (PG_FUNCTION_ARGS)
 
Datum tsquery_or (PG_FUNCTION_ARGS)
 
Datum tsquery_phrase_distance (PG_FUNCTION_ARGS)
 
Datum tsquery_phrase (PG_FUNCTION_ARGS)
 
Datum tsquery_not (PG_FUNCTION_ARGS)
 
static int CompareTSQ (TSQuery a, TSQuery b)
 
Datum tsquery_cmp (PG_FUNCTION_ARGS)
 
 CMPFUNC (tsquery_lt, res< 0)
 
 CMPFUNC (tsquery_le, res<=0)
 
 CMPFUNC (tsquery_eq, res==0)
 
 CMPFUNC (tsquery_ge, res >=0)
 
 CMPFUNC (tsquery_gt, res > 0)
 
 CMPFUNC (tsquery_ne, res !=0)
 
TSQuerySign makeTSQuerySign (TSQuery a)
 
static char ** collectTSQueryValues (TSQuery a, int *nvalues_p)
 
static int cmp_string (const void *a, const void *b)
 
Datum tsq_mcontains (PG_FUNCTION_ARGS)
 
Datum tsq_mcontained (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ CMPFUNC

#define CMPFUNC (   NAME,
  CONDITION 
)
Value:
Datum \
TSQuery a = PG_GETARG_TSQUERY_COPY(0); \
TSQuery b = PG_GETARG_TSQUERY_COPY(1); \
int res = CompareTSQ(a,b); \
PG_FREE_IF_COPY(b,1); \
PG_RETURN_BOOL( CONDITION ); \
} \
/* keep compiler quiet - no extra ; */ \
extern int no_such_variable
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
int b
Definition: isn.c:70
int a
Definition: isn.c:69
#define PG_GETARG_TSQUERY_COPY(n)
Definition: ts_type.h:267
static int CompareTSQ(TSQuery a, TSQuery b)
Definition: tsquery_op.c:189

Definition at line 227 of file tsquery_op.c.

Function Documentation

◆ cmp_string()

static int cmp_string ( const void *  a,
const void *  b 
)
static

Definition at line 298 of file tsquery_op.c.

299 {
300  const char *sa = *((char *const *) a);
301  const char *sb = *((char *const *) b);
302 
303  return strcmp(sa, sb);
304 }

References a, and b.

Referenced by tsq_mcontains().

◆ CMPFUNC() [1/6]

CMPFUNC ( tsquery_eq  ,
res  = =0 
)

◆ CMPFUNC() [2/6]

CMPFUNC ( tsquery_ge  ,
res >=  0 
)

◆ CMPFUNC() [3/6]

CMPFUNC ( tsquery_gt  ,
res  ,
 
)

◆ CMPFUNC() [4/6]

CMPFUNC ( tsquery_le  ,
res<=  0 
)

◆ CMPFUNC() [5/6]

CMPFUNC ( tsquery_lt  )

◆ CMPFUNC() [6/6]

CMPFUNC ( tsquery_ne  ,
res = 0 
)

◆ collectTSQueryValues()

static char** collectTSQueryValues ( TSQuery  a,
int *  nvalues_p 
)
static

Definition at line 267 of file tsquery_op.c.

268 {
269  QueryItem *ptr = GETQUERY(a);
270  char *operand = GETOPERAND(a);
271  char **values;
272  int nvalues = 0;
273  int i;
274 
275  values = (char **) palloc(sizeof(char *) * a->size);
276 
277  for (i = 0; i < a->size; i++)
278  {
279  if (ptr->type == QI_VAL)
280  {
281  int len = ptr->qoperand.length;
282  char *val;
283 
284  val = palloc(len + 1);
285  memcpy(val, operand + ptr->qoperand.distance, len);
286  val[len] = '\0';
287 
288  values[nvalues++] = val;
289  }
290  ptr++;
291  }
292 
293  *nvalues_p = nvalues;
294  return values;
295 }
#define GETQUERY(x)
Definition: _int.h:157
static Datum values[MAXATTR]
Definition: bootstrap.c:152
long val
Definition: informix.c:670
int i
Definition: isn.c:73
#define GETOPERAND(x)
Definition: ltree.h:165
void * palloc(Size size)
Definition: mcxt.c:1304
const void size_t len
uint32 distance
Definition: ts_type.h:172
uint32 length
Definition: ts_type.h:171
#define QI_VAL
Definition: ts_type.h:149
QueryOperand qoperand
Definition: ts_type.h:210
QueryItemType type
Definition: ts_type.h:208

References a, QueryOperand::distance, GETOPERAND, GETQUERY, i, len, QueryOperand::length, palloc(), QI_VAL, QueryItem::qoperand, QueryItem::type, val, and values.

Referenced by tsq_mcontains().

◆ CompareTSQ()

static int CompareTSQ ( TSQuery  a,
TSQuery  b 
)
static

Definition at line 189 of file tsquery_op.c.

190 {
191  if (a->size != b->size)
192  {
193  return (a->size < b->size) ? -1 : 1;
194  }
195  else if (VARSIZE(a) != VARSIZE(b))
196  {
197  return (VARSIZE(a) < VARSIZE(b)) ? -1 : 1;
198  }
199  else if (a->size != 0)
200  {
201  QTNode *an = QT2QTN(GETQUERY(a), GETOPERAND(a));
202  QTNode *bn = QT2QTN(GETQUERY(b), GETOPERAND(b));
203  int res = QTNodeCompare(an, bn);
204 
205  QTNFree(an);
206  QTNFree(bn);
207 
208  return res;
209  }
210 
211  return 0;
212 }
int QTNodeCompare(QTNode *an, QTNode *bn)
Definition: tsquery_util.c:97
QTNode * QT2QTN(QueryItem *in, char *operand)
Definition: tsquery_util.c:25
void QTNFree(QTNode *in)
Definition: tsquery_util.c:64
#define VARSIZE(PTR)
Definition: varatt.h:279

References a, b, GETOPERAND, GETQUERY, QT2QTN(), QTNFree(), QTNodeCompare(), res, and VARSIZE.

Referenced by tsquery_cmp().

◆ join_tsqueries()

static QTNode* join_tsqueries ( TSQuery  a,
TSQuery  b,
int8  operator,
uint16  distance 
)
static

Definition at line 33 of file tsquery_op.c.

34 {
35  QTNode *res = (QTNode *) palloc0(sizeof(QTNode));
36 
37  res->flags |= QTN_NEEDFREE;
38 
39  res->valnode = (QueryItem *) palloc0(sizeof(QueryItem));
40  res->valnode->type = QI_OPR;
41  res->valnode->qoperator.oper = operator;
42  if (operator == OP_PHRASE)
43  res->valnode->qoperator.distance = distance;
44 
45  res->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);
46  res->child[0] = QT2QTN(GETQUERY(b), GETOPERAND(b));
47  res->child[1] = QT2QTN(GETQUERY(a), GETOPERAND(a));
48  res->nchild = 2;
49 
50  return res;
51 }
void * palloc0(Size size)
Definition: mcxt.c:1334
#define QI_OPR
Definition: ts_type.h:150
#define OP_PHRASE
Definition: ts_type.h:182
#define QTN_NEEDFREE
Definition: ts_utils.h:245

References a, b, GETOPERAND, GETQUERY, OP_PHRASE, palloc0(), QI_OPR, QT2QTN(), QTN_NEEDFREE, and res.

Referenced by tsquery_and(), tsquery_or(), and tsquery_phrase_distance().

◆ 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:674
int32 valcrc
Definition: ts_type.h:164
#define TSQS_SIGLEN
Definition: ts_utils.h:251
uint64 TSQuerySign
Definition: ts_utils.h:249

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

Referenced by gtsquery_compress(), and gtsquery_consistent().

◆ tsq_mcontained()

Datum tsq_mcontained ( PG_FUNCTION_ARGS  )

Definition at line 354 of file tsquery_op.c.

355 {
357  PG_GETARG_DATUM(1),
358  PG_GETARG_DATUM(0)));
359 }
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:644
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
Datum tsq_mcontains(PG_FUNCTION_ARGS)
Definition: tsquery_op.c:307

References DirectFunctionCall2, PG_GETARG_DATUM, PG_RETURN_DATUM, and tsq_mcontains().

◆ tsq_mcontains()

Datum tsq_mcontains ( PG_FUNCTION_ARGS  )

Definition at line 307 of file tsquery_op.c.

308 {
309  TSQuery query = PG_GETARG_TSQUERY(0);
310  TSQuery ex = PG_GETARG_TSQUERY(1);
311  char **query_values;
312  int query_nvalues;
313  char **ex_values;
314  int ex_nvalues;
315  bool result = true;
316 
317  /* Extract the query terms into arrays */
318  query_values = collectTSQueryValues(query, &query_nvalues);
319  ex_values = collectTSQueryValues(ex, &ex_nvalues);
320 
321  /* Sort and remove duplicates from both arrays */
322  qsort(query_values, query_nvalues, sizeof(char *), cmp_string);
323  query_nvalues = qunique(query_values, query_nvalues, sizeof(char *),
324  cmp_string);
325  qsort(ex_values, ex_nvalues, sizeof(char *), cmp_string);
326  ex_nvalues = qunique(ex_values, ex_nvalues, sizeof(char *), cmp_string);
327 
328  if (ex_nvalues > query_nvalues)
329  result = false;
330  else
331  {
332  int i;
333  int j = 0;
334 
335  for (i = 0; i < ex_nvalues; i++)
336  {
337  for (; j < query_nvalues; j++)
338  {
339  if (strcmp(ex_values[i], query_values[j]) == 0)
340  break;
341  }
342  if (j == query_nvalues)
343  {
344  result = false;
345  break;
346  }
347  }
348  }
349 
350  PG_RETURN_BOOL(result);
351 }
int j
Definition: isn.c:74
#define qsort(a, b, c, d)
Definition: port.h:449
static size_t qunique(void *array, size_t elements, size_t width, int(*compare)(const void *, const void *))
Definition: qunique.h:21
#define PG_GETARG_TSQUERY(n)
Definition: ts_type.h:266
static char ** collectTSQueryValues(TSQuery a, int *nvalues_p)
Definition: tsquery_op.c:267
static int cmp_string(const void *a, const void *b)
Definition: tsquery_op.c:298

References cmp_string(), collectTSQueryValues(), i, j, PG_GETARG_TSQUERY, PG_RETURN_BOOL, qsort, and qunique().

Referenced by tsq_mcontained().

◆ tsquery_and()

Datum tsquery_and ( PG_FUNCTION_ARGS  )

Definition at line 54 of file tsquery_op.c.

55 {
58  QTNode *res;
59  TSQuery query;
60 
61  if (a->size == 0)
62  {
63  PG_FREE_IF_COPY(a, 1);
65  }
66  else if (b->size == 0)
67  {
68  PG_FREE_IF_COPY(b, 1);
70  }
71 
72  res = join_tsqueries(a, b, OP_AND, 0);
73 
74  query = QTN2QT(res);
75 
76  QTNFree(res);
77  PG_FREE_IF_COPY(a, 0);
78  PG_FREE_IF_COPY(b, 1);
79 
80  PG_RETURN_TSQUERY(query);
81 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define PG_RETURN_TSQUERY(x)
Definition: ts_type.h:268
#define OP_AND
Definition: ts_type.h:180
static QTNode * join_tsqueries(TSQuery a, TSQuery b, int8 operator, uint16 distance)
Definition: tsquery_op.c:33
TSQuery QTN2QT(QTNode *in)
Definition: tsquery_util.c:363

References a, b, join_tsqueries(), OP_AND, PG_FREE_IF_COPY, PG_GETARG_TSQUERY_COPY, PG_RETURN_POINTER, PG_RETURN_TSQUERY, QTN2QT(), QTNFree(), and res.

◆ tsquery_cmp()

Datum tsquery_cmp ( PG_FUNCTION_ARGS  )

Definition at line 215 of file tsquery_op.c.

216 {
219  int res = CompareTSQ(a, b);
220 
221  PG_FREE_IF_COPY(a, 0);
222  PG_FREE_IF_COPY(b, 1);
223 
225 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354

References a, b, CompareTSQ(), PG_FREE_IF_COPY, PG_GETARG_TSQUERY_COPY, PG_RETURN_INT32, and res.

◆ tsquery_not()

Datum tsquery_not ( PG_FUNCTION_ARGS  )

Definition at line 159 of file tsquery_op.c.

160 {
162  QTNode *res;
163  TSQuery query;
164 
165  if (a->size == 0)
167 
168  res = (QTNode *) palloc0(sizeof(QTNode));
169 
170  res->flags |= QTN_NEEDFREE;
171 
172  res->valnode = (QueryItem *) palloc0(sizeof(QueryItem));
173  res->valnode->type = QI_OPR;
174  res->valnode->qoperator.oper = OP_NOT;
175 
176  res->child = (QTNode **) palloc0(sizeof(QTNode *));
177  res->child[0] = QT2QTN(GETQUERY(a), GETOPERAND(a));
178  res->nchild = 1;
179 
180  query = QTN2QT(res);
181 
182  QTNFree(res);
183  PG_FREE_IF_COPY(a, 0);
184 
185  PG_RETURN_POINTER(query);
186 }
#define OP_NOT
Definition: ts_type.h:179

References a, GETOPERAND, GETQUERY, OP_NOT, palloc0(), PG_FREE_IF_COPY, PG_GETARG_TSQUERY_COPY, PG_RETURN_POINTER, QI_OPR, QT2QTN(), QTN2QT(), QTN_NEEDFREE, QTNFree(), and res.

◆ tsquery_numnode()

Datum tsquery_numnode ( PG_FUNCTION_ARGS  )

Definition at line 23 of file tsquery_op.c.

24 {
25  TSQuery query = PG_GETARG_TSQUERY(0);
26  int nnode = query->size;
27 
28  PG_FREE_IF_COPY(query, 0);
29  PG_RETURN_INT32(nnode);
30 }
int32 size
Definition: ts_type.h:221

References PG_FREE_IF_COPY, PG_GETARG_TSQUERY, PG_RETURN_INT32, and TSQueryData::size.

◆ tsquery_or()

Datum tsquery_or ( PG_FUNCTION_ARGS  )

Definition at line 84 of file tsquery_op.c.

85 {
88  QTNode *res;
89  TSQuery query;
90 
91  if (a->size == 0)
92  {
93  PG_FREE_IF_COPY(a, 1);
95  }
96  else if (b->size == 0)
97  {
98  PG_FREE_IF_COPY(b, 1);
100  }
101 
102  res = join_tsqueries(a, b, OP_OR, 0);
103 
104  query = QTN2QT(res);
105 
106  QTNFree(res);
107  PG_FREE_IF_COPY(a, 0);
108  PG_FREE_IF_COPY(b, 1);
109 
110  PG_RETURN_TSQUERY(query);
111 }
#define OP_OR
Definition: ts_type.h:181

References a, b, join_tsqueries(), OP_OR, PG_FREE_IF_COPY, PG_GETARG_TSQUERY_COPY, PG_RETURN_POINTER, PG_RETURN_TSQUERY, QTN2QT(), QTNFree(), and res.

◆ tsquery_phrase()

Datum tsquery_phrase ( PG_FUNCTION_ARGS  )

Definition at line 150 of file tsquery_op.c.

151 {
153  PG_GETARG_DATUM(0),
154  PG_GETARG_DATUM(1),
155  Int32GetDatum(1)));
156 }
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:646
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
Datum tsquery_phrase_distance(PG_FUNCTION_ARGS)
Definition: tsquery_op.c:114

References DirectFunctionCall3, Int32GetDatum(), PG_GETARG_DATUM, PG_RETURN_DATUM, and tsquery_phrase_distance().

◆ tsquery_phrase_distance()

Datum tsquery_phrase_distance ( PG_FUNCTION_ARGS  )

Definition at line 114 of file tsquery_op.c.

115 {
118  QTNode *res;
119  TSQuery query;
120  int32 distance = PG_GETARG_INT32(2);
121 
122  if (distance < 0 || distance > MAXENTRYPOS)
123  ereport(ERROR,
124  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
125  errmsg("distance in phrase operator must be an integer value between zero and %d inclusive",
126  MAXENTRYPOS)));
127  if (a->size == 0)
128  {
129  PG_FREE_IF_COPY(a, 1);
131  }
132  else if (b->size == 0)
133  {
134  PG_FREE_IF_COPY(b, 1);
136  }
137 
138  res = join_tsqueries(a, b, OP_PHRASE, (uint16) distance);
139 
140  query = QTN2QT(res);
141 
142  QTNFree(res);
143  PG_FREE_IF_COPY(a, 0);
144  PG_FREE_IF_COPY(b, 1);
145 
146  PG_RETURN_TSQUERY(query);
147 }
unsigned short uint16
Definition: c.h:492
signed int int32
Definition: c.h:481
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define MAXENTRYPOS
Definition: ts_type.h:85

References a, b, ereport, errcode(), errmsg(), ERROR, join_tsqueries(), MAXENTRYPOS, OP_PHRASE, PG_FREE_IF_COPY, PG_GETARG_INT32, PG_GETARG_TSQUERY_COPY, PG_RETURN_POINTER, PG_RETURN_TSQUERY, QTN2QT(), QTNFree(), and res.

Referenced by tsquery_phrase().