Fix compiler warnings on Sun Studio of the sort
[PostgreSQL.git] / src / backend / utils / adt / tsquery_op.c
blobc7ef33ab9416cfed89f6d250d57290dc8fc59524
1 /*-------------------------------------------------------------------------
3 * tsquery_op.c
4 * Various operations with tsquery
6 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
9 * IDENTIFICATION
10 * $PostgreSQL$
12 *-------------------------------------------------------------------------
15 #include "postgres.h"
17 #include "tsearch/ts_type.h"
18 #include "tsearch/ts_locale.h"
19 #include "tsearch/ts_utils.h"
20 #include "utils/pg_crc.h"
22 Datum
23 tsquery_numnode(PG_FUNCTION_ARGS)
25 TSQuery query = PG_GETARG_TSQUERY(0);
26 int nnode = query->size;
28 PG_FREE_IF_COPY(query, 0);
29 PG_RETURN_INT32(nnode);
32 static QTNode *
33 join_tsqueries(TSQuery a, TSQuery b, int8 operator)
35 QTNode *res = (QTNode *) palloc0(sizeof(QTNode));
37 res->flags |= QTN_NEEDFREE;
39 res->valnode = (QueryItem *) palloc0(sizeof(QueryItem));
40 res->valnode->type = QI_OPR;
41 res->valnode->operator.oper = operator;
43 res->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);
44 res->child[0] = QT2QTN(GETQUERY(b), GETOPERAND(b));
45 res->child[1] = QT2QTN(GETQUERY(a), GETOPERAND(a));
46 res->nchild = 2;
48 return res;
51 Datum
52 tsquery_and(PG_FUNCTION_ARGS)
54 TSQuery a = PG_GETARG_TSQUERY_COPY(0);
55 TSQuery b = PG_GETARG_TSQUERY_COPY(1);
56 QTNode *res;
57 TSQuery query;
59 if (a->size == 0)
61 PG_FREE_IF_COPY(a, 1);
62 PG_RETURN_POINTER(b);
64 else if (b->size == 0)
66 PG_FREE_IF_COPY(b, 1);
67 PG_RETURN_POINTER(a);
70 res = join_tsqueries(a, b, OP_AND);
72 query = QTN2QT(res);
74 QTNFree(res);
75 PG_FREE_IF_COPY(a, 0);
76 PG_FREE_IF_COPY(b, 1);
78 PG_RETURN_TSQUERY(query);
81 Datum
82 tsquery_or(PG_FUNCTION_ARGS)
84 TSQuery a = PG_GETARG_TSQUERY_COPY(0);
85 TSQuery b = PG_GETARG_TSQUERY_COPY(1);
86 QTNode *res;
87 TSQuery query;
89 if (a->size == 0)
91 PG_FREE_IF_COPY(a, 1);
92 PG_RETURN_POINTER(b);
94 else if (b->size == 0)
96 PG_FREE_IF_COPY(b, 1);
97 PG_RETURN_POINTER(a);
100 res = join_tsqueries(a, b, OP_OR);
102 query = QTN2QT(res);
104 QTNFree(res);
105 PG_FREE_IF_COPY(a, 0);
106 PG_FREE_IF_COPY(b, 1);
108 PG_RETURN_POINTER(query);
111 Datum
112 tsquery_not(PG_FUNCTION_ARGS)
114 TSQuery a = PG_GETARG_TSQUERY_COPY(0);
115 QTNode *res;
116 TSQuery query;
118 if (a->size == 0)
119 PG_RETURN_POINTER(a);
121 res = (QTNode *) palloc0(sizeof(QTNode));
123 res->flags |= QTN_NEEDFREE;
125 res->valnode = (QueryItem *) palloc0(sizeof(QueryItem));
126 res->valnode->type = QI_OPR;
127 res->valnode->operator.oper = OP_NOT;
129 res->child = (QTNode **) palloc0(sizeof(QTNode *));
130 res->child[0] = QT2QTN(GETQUERY(a), GETOPERAND(a));
131 res->nchild = 1;
133 query = QTN2QT(res);
135 QTNFree(res);
136 PG_FREE_IF_COPY(a, 0);
138 PG_RETURN_POINTER(query);
141 static int
142 CompareTSQ(TSQuery a, TSQuery b)
144 if (a->size != b->size)
146 return (a->size < b->size) ? -1 : 1;
148 else if (VARSIZE(a) != VARSIZE(b))
150 return (VARSIZE(a) < VARSIZE(b)) ? -1 : 1;
152 else
154 QTNode *an = QT2QTN(GETQUERY(a), GETOPERAND(a));
155 QTNode *bn = QT2QTN(GETQUERY(b), GETOPERAND(b));
156 int res = QTNodeCompare(an, bn);
158 QTNFree(an);
159 QTNFree(bn);
161 return res;
164 return 0;
167 Datum
168 tsquery_cmp(PG_FUNCTION_ARGS)
170 TSQuery a = PG_GETARG_TSQUERY_COPY(0);
171 TSQuery b = PG_GETARG_TSQUERY_COPY(1);
172 int res = CompareTSQ(a, b);
174 PG_FREE_IF_COPY(a, 0);
175 PG_FREE_IF_COPY(b, 1);
177 PG_RETURN_INT32(res);
180 #define CMPFUNC( NAME, CONDITION ) \
181 Datum \
182 NAME(PG_FUNCTION_ARGS) { \
183 TSQuery a = PG_GETARG_TSQUERY_COPY(0); \
184 TSQuery b = PG_GETARG_TSQUERY_COPY(1); \
185 int res = CompareTSQ(a,b); \
187 PG_FREE_IF_COPY(a,0); \
188 PG_FREE_IF_COPY(b,1); \
190 PG_RETURN_BOOL( CONDITION ); \
192 /* keep compiler quiet - no extra ; */ \
193 extern int no_such_variable
195 CMPFUNC(tsquery_lt, res < 0);
196 CMPFUNC(tsquery_le, res <= 0);
197 CMPFUNC(tsquery_eq, res == 0);
198 CMPFUNC(tsquery_ge, res >= 0);
199 CMPFUNC(tsquery_gt, res > 0);
200 CMPFUNC(tsquery_ne, res != 0);
202 TSQuerySign
203 makeTSQuerySign(TSQuery a)
205 int i;
206 QueryItem *ptr = GETQUERY(a);
207 TSQuerySign sign = 0;
209 for (i = 0; i < a->size; i++)
211 if (ptr->type == QI_VAL)
212 sign |= ((TSQuerySign) 1) << (ptr->operand.valcrc % TSQS_SIGLEN);
213 ptr++;
216 return sign;
219 Datum
220 tsq_mcontains(PG_FUNCTION_ARGS)
222 TSQuery query = PG_GETARG_TSQUERY(0);
223 TSQuery ex = PG_GETARG_TSQUERY(1);
224 TSQuerySign sq,
226 int i,
228 QueryItem *iq,
229 *ie;
231 if (query->size < ex->size)
233 PG_FREE_IF_COPY(query, 0);
234 PG_FREE_IF_COPY(ex, 1);
236 PG_RETURN_BOOL(false);
239 sq = makeTSQuerySign(query);
240 se = makeTSQuerySign(ex);
242 if ((sq & se) != se)
244 PG_FREE_IF_COPY(query, 0);
245 PG_FREE_IF_COPY(ex, 1);
247 PG_RETURN_BOOL(false);
250 ie = GETQUERY(ex);
252 for (i = 0; i < ex->size; i++)
254 iq = GETQUERY(query);
255 if (ie[i].type != QI_VAL)
256 continue;
257 for (j = 0; j < query->size; j++)
258 if (iq[j].type == QI_VAL && ie[i].operand.valcrc == iq[j].operand.valcrc)
260 j = query->size + 1;
261 break;
263 if (j == query->size)
265 PG_FREE_IF_COPY(query, 0);
266 PG_FREE_IF_COPY(ex, 1);
268 PG_RETURN_BOOL(false);
272 PG_FREE_IF_COPY(query, 0);
273 PG_FREE_IF_COPY(ex, 1);
275 PG_RETURN_BOOL(true);
278 Datum
279 tsq_mcontained(PG_FUNCTION_ARGS)
281 PG_RETURN_DATUM(
282 DirectFunctionCall2(
283 tsq_mcontains,
284 PG_GETARG_DATUM(1),
285 PG_GETARG_DATUM(0)