PostgreSQL Source Code  git master
tsquery_op.c File Reference
#include "postgres.h"
#include "lib/qunique.h"
#include "tsearch/ts_utils.h"
#include "utils/builtins.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_GETARG_TSQUERY_COPY(n)
Definition: ts_type.h:239
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
static int CompareTSQ(TSQuery a, TSQuery b)
Definition: tsquery_op.c:188
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
#define PG_FUNCTION_ARGS
Definition: fmgr.h:188

Definition at line 226 of file tsquery_op.c.

Function Documentation

◆ cmp_string()

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

Definition at line 297 of file tsquery_op.c.

Referenced by tsq_mcontains().

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

◆ CMPFUNC() [1/6]

CMPFUNC ( tsquery_lt  )

◆ CMPFUNC() [2/6]

CMPFUNC ( tsquery_le  ,
res<=  0 
)

◆ CMPFUNC() [3/6]

CMPFUNC ( tsquery_eq  ,
res  = =0 
)

◆ CMPFUNC() [4/6]

CMPFUNC ( tsquery_ge  ,
res >=  0 
)

◆ CMPFUNC() [5/6]

CMPFUNC ( tsquery_gt  ,
res  ,
 
)

◆ CMPFUNC() [6/6]

CMPFUNC ( tsquery_ne  ,
res !  = 0 
)

◆ collectTSQueryValues()

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

Definition at line 266 of file tsquery_op.c.

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

Referenced by tsq_mcontains().

267 {
268  QueryItem *ptr = GETQUERY(a);
269  char *operand = GETOPERAND(a);
270  char **values;
271  int nvalues = 0;
272  int i;
273 
274  values = (char **) palloc(sizeof(char *) * a->size);
275 
276  for (i = 0; i < a->size; i++)
277  {
278  if (ptr->type == QI_VAL)
279  {
280  int len = ptr->qoperand.length;
281  char *val;
282 
283  val = palloc(len + 1);
284  memcpy(val, operand + ptr->qoperand.distance, len);
285  val[len] = '\0';
286 
287  values[nvalues++] = val;
288  }
289  ptr++;
290  }
291 
292  *nvalues_p = nvalues;
293  return values;
294 }
#define QI_VAL
Definition: ts_type.h:134
uint32 distance
Definition: ts_type.h:158
#define GETQUERY(x)
Definition: _int.h:136
#define GETOPERAND(x)
Definition: ltree.h:118
QueryItemType type
Definition: ts_type.h:195
uint32 length
Definition: ts_type.h:158
static Datum values[MAXATTR]
Definition: bootstrap.c:167
void * palloc(Size size)
Definition: mcxt.c:949
int32 size
Definition: ts_type.h:208
int i
QueryOperand qoperand
Definition: ts_type.h:197
long val
Definition: informix.c:664

◆ CompareTSQ()

static int CompareTSQ ( TSQuery  a,
TSQuery  b 
)
static

Definition at line 188 of file tsquery_op.c.

References GETOPERAND, GETQUERY, QT2QTN(), QTNFree(), QTNodeCompare(), TSQueryData::size, and VARSIZE.

Referenced by tsquery_cmp().

189 {
190  if (a->size != b->size)
191  {
192  return (a->size < b->size) ? -1 : 1;
193  }
194  else if (VARSIZE(a) != VARSIZE(b))
195  {
196  return (VARSIZE(a) < VARSIZE(b)) ? -1 : 1;
197  }
198  else if (a->size != 0)
199  {
200  QTNode *an = QT2QTN(GETQUERY(a), GETOPERAND(a));
201  QTNode *bn = QT2QTN(GETQUERY(b), GETOPERAND(b));
202  int res = QTNodeCompare(an, bn);
203 
204  QTNFree(an);
205  QTNFree(bn);
206 
207  return res;
208  }
209 
210  return 0;
211 }
void QTNFree(QTNode *in)
Definition: tsquery_util.c:63
QTNode * QT2QTN(QueryItem *in, char *operand)
Definition: tsquery_util.c:24
#define VARSIZE(PTR)
Definition: postgres.h:303
#define GETQUERY(x)
Definition: _int.h:136
#define GETOPERAND(x)
Definition: ltree.h:118
int32 size
Definition: ts_type.h:208
int QTNodeCompare(QTNode *an, QTNode *bn)
Definition: tsquery_util.c:96

◆ join_tsqueries()

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

Definition at line 32 of file tsquery_op.c.

References QTNode::child, NODE::distance, QueryOperator::distance, QTNode::flags, GETOPERAND, GETQUERY, QTNode::nchild, OP_PHRASE, QueryOperator::oper, palloc0(), QI_OPR, QueryItem::qoperator, QT2QTN(), QTN_NEEDFREE, QueryItem::type, and QTNode::valnode.

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

33 {
34  QTNode *res = (QTNode *) palloc0(sizeof(QTNode));
35 
36  res->flags |= QTN_NEEDFREE;
37 
38  res->valnode = (QueryItem *) palloc0(sizeof(QueryItem));
39  res->valnode->type = QI_OPR;
40  res->valnode->qoperator.oper = operator;
41  if (operator == OP_PHRASE)
42  res->valnode->qoperator.distance = distance;
43 
44  res->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);
45  res->child[0] = QT2QTN(GETQUERY(b), GETOPERAND(b));
46  res->child[1] = QT2QTN(GETQUERY(a), GETOPERAND(a));
47  res->nchild = 2;
48 
49  return res;
50 }
QueryOperator qoperator
Definition: ts_type.h:196
QTNode * QT2QTN(QueryItem *in, char *operand)
Definition: tsquery_util.c:24
int16 distance
Definition: ts_type.h:183
#define GETQUERY(x)
Definition: _int.h:136
#define GETOPERAND(x)
Definition: ltree.h:118
#define QI_OPR
Definition: ts_type.h:135
QueryItemType type
Definition: ts_type.h:195
void * palloc0(Size size)
Definition: mcxt.c:980
#define OP_PHRASE
Definition: ts_type.h:169
struct QTNode ** child
Definition: ts_utils.h:223
#define QTN_NEEDFREE
Definition: ts_utils.h:227
QueryItem * valnode
Definition: ts_utils.h:218
int32 nchild
Definition: ts_utils.h:220
uint32 flags
Definition: ts_utils.h:219

◆ makeTSQuerySign()

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:233
#define QI_VAL
Definition: ts_type.h:134
#define GETQUERY(x)
Definition: _int.h:136
char sign
Definition: informix.c:668
uint64 TSQuerySign
Definition: ts_utils.h:231
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

◆ tsq_mcontained()

Datum tsq_mcontained ( PG_FUNCTION_ARGS  )

Definition at line 353 of file tsquery_op.c.

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

354 {
356  PG_GETARG_DATUM(1),
357  PG_GETARG_DATUM(0)));
358 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
Datum tsq_mcontains(PG_FUNCTION_ARGS)
Definition: tsquery_op.c:306
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:617

◆ tsq_mcontains()

Datum tsq_mcontains ( PG_FUNCTION_ARGS  )

Definition at line 306 of file tsquery_op.c.

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

Referenced by tsq_mcontained().

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

◆ tsquery_and()

Datum tsquery_and ( PG_FUNCTION_ARGS  )

Definition at line 53 of file tsquery_op.c.

References join_tsqueries(), OP_AND, PG_FREE_IF_COPY, PG_GETARG_TSQUERY_COPY, PG_RETURN_POINTER, PG_RETURN_TSQUERY, QTN2QT(), QTNFree(), and TSQueryData::size.

54 {
57  QTNode *res;
58  TSQuery query;
59 
60  if (a->size == 0)
61  {
62  PG_FREE_IF_COPY(a, 1);
64  }
65  else if (b->size == 0)
66  {
67  PG_FREE_IF_COPY(b, 1);
69  }
70 
71  res = join_tsqueries(a, b, OP_AND, 0);
72 
73  query = QTN2QT(res);
74 
75  QTNFree(res);
76  PG_FREE_IF_COPY(a, 0);
77  PG_FREE_IF_COPY(b, 1);
78 
79  PG_RETURN_TSQUERY(query);
80 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
void QTNFree(QTNode *in)
Definition: tsquery_util.c:63
static QTNode * join_tsqueries(TSQuery a, TSQuery b, int8 operator, uint16 distance)
Definition: tsquery_op.c:32
#define PG_RETURN_TSQUERY(x)
Definition: ts_type.h:240
#define OP_AND
Definition: ts_type.h:167
#define PG_GETARG_TSQUERY_COPY(n)
Definition: ts_type.h:239
TSQuery QTN2QT(QTNode *in)
Definition: tsquery_util.c:362
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
int32 size
Definition: ts_type.h:208

◆ tsquery_cmp()

Datum tsquery_cmp ( PG_FUNCTION_ARGS  )

Definition at line 214 of file tsquery_op.c.

References CompareTSQ(), PG_FREE_IF_COPY, PG_GETARG_TSQUERY_COPY, and PG_RETURN_INT32.

215 {
218  int res = CompareTSQ(a, b);
219 
220  PG_FREE_IF_COPY(a, 0);
221  PG_FREE_IF_COPY(b, 1);
222 
223  PG_RETURN_INT32(res);
224 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
#define PG_GETARG_TSQUERY_COPY(n)
Definition: ts_type.h:239
static int CompareTSQ(TSQuery a, TSQuery b)
Definition: tsquery_op.c:188
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255

◆ tsquery_not()

Datum tsquery_not ( PG_FUNCTION_ARGS  )

Definition at line 158 of file tsquery_op.c.

References QTNode::child, QTNode::flags, GETOPERAND, GETQUERY, QTNode::nchild, OP_NOT, QueryOperator::oper, palloc0(), PG_FREE_IF_COPY, PG_GETARG_TSQUERY_COPY, PG_RETURN_POINTER, QI_OPR, QueryItem::qoperator, QT2QTN(), QTN2QT(), QTN_NEEDFREE, QTNFree(), TSQueryData::size, QueryItem::type, and QTNode::valnode.

159 {
161  QTNode *res;
162  TSQuery query;
163 
164  if (a->size == 0)
166 
167  res = (QTNode *) palloc0(sizeof(QTNode));
168 
169  res->flags |= QTN_NEEDFREE;
170 
171  res->valnode = (QueryItem *) palloc0(sizeof(QueryItem));
172  res->valnode->type = QI_OPR;
173  res->valnode->qoperator.oper = OP_NOT;
174 
175  res->child = (QTNode **) palloc0(sizeof(QTNode *));
176  res->child[0] = QT2QTN(GETQUERY(a), GETOPERAND(a));
177  res->nchild = 1;
178 
179  query = QTN2QT(res);
180 
181  QTNFree(res);
182  PG_FREE_IF_COPY(a, 0);
183 
184  PG_RETURN_POINTER(query);
185 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
QueryOperator qoperator
Definition: ts_type.h:196
void QTNFree(QTNode *in)
Definition: tsquery_util.c:63
QTNode * QT2QTN(QueryItem *in, char *operand)
Definition: tsquery_util.c:24
#define GETQUERY(x)
Definition: _int.h:136
#define GETOPERAND(x)
Definition: ltree.h:118
#define PG_GETARG_TSQUERY_COPY(n)
Definition: ts_type.h:239
TSQuery QTN2QT(QTNode *in)
Definition: tsquery_util.c:362
#define QI_OPR
Definition: ts_type.h:135
QueryItemType type
Definition: ts_type.h:195
void * palloc0(Size size)
Definition: mcxt.c:980
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
struct QTNode ** child
Definition: ts_utils.h:223
#define QTN_NEEDFREE
Definition: ts_utils.h:227
QueryItem * valnode
Definition: ts_utils.h:218
int32 nchild
Definition: ts_utils.h:220
int32 size
Definition: ts_type.h:208
uint32 flags
Definition: ts_utils.h:219
#define OP_NOT
Definition: ts_type.h:166

◆ tsquery_numnode()

Datum tsquery_numnode ( PG_FUNCTION_ARGS  )

Definition at line 22 of file tsquery_op.c.

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

23 {
24  TSQuery query = PG_GETARG_TSQUERY(0);
25  int nnode = query->size;
26 
27  PG_FREE_IF_COPY(query, 0);
28  PG_RETURN_INT32(nnode);
29 }
#define PG_GETARG_TSQUERY(n)
Definition: ts_type.h:238
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
int32 size
Definition: ts_type.h:208

◆ tsquery_or()

Datum tsquery_or ( PG_FUNCTION_ARGS  )

Definition at line 83 of file tsquery_op.c.

References join_tsqueries(), OP_OR, PG_FREE_IF_COPY, PG_GETARG_TSQUERY_COPY, PG_RETURN_POINTER, PG_RETURN_TSQUERY, QTN2QT(), QTNFree(), and TSQueryData::size.

84 {
87  QTNode *res;
88  TSQuery query;
89 
90  if (a->size == 0)
91  {
92  PG_FREE_IF_COPY(a, 1);
94  }
95  else if (b->size == 0)
96  {
97  PG_FREE_IF_COPY(b, 1);
99  }
100 
101  res = join_tsqueries(a, b, OP_OR, 0);
102 
103  query = QTN2QT(res);
104 
105  QTNFree(res);
106  PG_FREE_IF_COPY(a, 0);
107  PG_FREE_IF_COPY(b, 1);
108 
109  PG_RETURN_TSQUERY(query);
110 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
void QTNFree(QTNode *in)
Definition: tsquery_util.c:63
#define OP_OR
Definition: ts_type.h:168
static QTNode * join_tsqueries(TSQuery a, TSQuery b, int8 operator, uint16 distance)
Definition: tsquery_op.c:32
#define PG_RETURN_TSQUERY(x)
Definition: ts_type.h:240
#define PG_GETARG_TSQUERY_COPY(n)
Definition: ts_type.h:239
TSQuery QTN2QT(QTNode *in)
Definition: tsquery_util.c:362
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
int32 size
Definition: ts_type.h:208

◆ tsquery_phrase()

Datum tsquery_phrase ( PG_FUNCTION_ARGS  )

Definition at line 149 of file tsquery_op.c.

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

150 {
152  PG_GETARG_DATUM(0),
153  PG_GETARG_DATUM(1),
154  Int32GetDatum(1)));
155 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
Datum tsquery_phrase_distance(PG_FUNCTION_ARGS)
Definition: tsquery_op.c:113
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:619
#define Int32GetDatum(X)
Definition: postgres.h:479

◆ tsquery_phrase_distance()

Datum tsquery_phrase_distance ( PG_FUNCTION_ARGS  )

Definition at line 113 of file tsquery_op.c.

References NODE::distance, 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 TSQueryData::size.

Referenced by tsquery_phrase().

114 {
117  QTNode *res;
118  TSQuery query;
119  int32 distance = PG_GETARG_INT32(2);
120 
121  if (distance < 0 || distance > MAXENTRYPOS)
122  ereport(ERROR,
123  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
124  errmsg("distance in phrase operator should be non-negative and less than %d",
125  MAXENTRYPOS)));
126  if (a->size == 0)
127  {
128  PG_FREE_IF_COPY(a, 1);
130  }
131  else if (b->size == 0)
132  {
133  PG_FREE_IF_COPY(b, 1);
135  }
136 
137  res = join_tsqueries(a, b, OP_PHRASE, (uint16) distance);
138 
139  query = QTN2QT(res);
140 
141  QTNFree(res);
142  PG_FREE_IF_COPY(a, 0);
143  PG_FREE_IF_COPY(b, 1);
144 
145  PG_RETURN_TSQUERY(query);
146 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
void QTNFree(QTNode *in)
Definition: tsquery_util.c:63
int errcode(int sqlerrcode)
Definition: elog.c:608
signed int int32
Definition: c.h:347
static QTNode * join_tsqueries(TSQuery a, TSQuery b, int8 operator, uint16 distance)
Definition: tsquery_op.c:32
#define PG_RETURN_TSQUERY(x)
Definition: ts_type.h:240
#define PG_GETARG_TSQUERY_COPY(n)
Definition: ts_type.h:239
unsigned short uint16
Definition: c.h:358
#define ERROR
Definition: elog.h:43
TSQuery QTN2QT(QTNode *in)
Definition: tsquery_util.c:362
#define ereport(elevel, rest)
Definition: elog.h:141
#define OP_PHRASE
Definition: ts_type.h:169
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
int errmsg(const char *fmt,...)
Definition: elog.c:822
int32 size
Definition: ts_type.h:208
#define MAXENTRYPOS
Definition: ts_type.h:85