1 /*-------------------------------------------------------------------------
4 * Various operations with tsquery
6 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
12 *-------------------------------------------------------------------------
17 #include "tsearch/ts_type.h"
18 #include "tsearch/ts_locale.h"
19 #include "tsearch/ts_utils.h"
20 #include "utils/pg_crc.h"
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
);
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
));
52 tsquery_and(PG_FUNCTION_ARGS
)
54 TSQuery a
= PG_GETARG_TSQUERY_COPY(0);
55 TSQuery b
= PG_GETARG_TSQUERY_COPY(1);
61 PG_FREE_IF_COPY(a
, 1);
64 else if (b
->size
== 0)
66 PG_FREE_IF_COPY(b
, 1);
70 res
= join_tsqueries(a
, b
, OP_AND
);
75 PG_FREE_IF_COPY(a
, 0);
76 PG_FREE_IF_COPY(b
, 1);
78 PG_RETURN_TSQUERY(query
);
82 tsquery_or(PG_FUNCTION_ARGS
)
84 TSQuery a
= PG_GETARG_TSQUERY_COPY(0);
85 TSQuery b
= PG_GETARG_TSQUERY_COPY(1);
91 PG_FREE_IF_COPY(a
, 1);
94 else if (b
->size
== 0)
96 PG_FREE_IF_COPY(b
, 1);
100 res
= join_tsqueries(a
, b
, OP_OR
);
105 PG_FREE_IF_COPY(a
, 0);
106 PG_FREE_IF_COPY(b
, 1);
108 PG_RETURN_POINTER(query
);
112 tsquery_not(PG_FUNCTION_ARGS
)
114 TSQuery a
= PG_GETARG_TSQUERY_COPY(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
));
136 PG_FREE_IF_COPY(a
, 0);
138 PG_RETURN_POINTER(query
);
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;
154 QTNode
*an
= QT2QTN(GETQUERY(a
), GETOPERAND(a
));
155 QTNode
*bn
= QT2QTN(GETQUERY(b
), GETOPERAND(b
));
156 int res
= QTNodeCompare(an
, bn
);
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 ) \
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);
203 makeTSQuerySign(TSQuery a
)
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
);
220 tsq_mcontains(PG_FUNCTION_ARGS
)
222 TSQuery query
= PG_GETARG_TSQUERY(0);
223 TSQuery ex
= PG_GETARG_TSQUERY(1);
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
);
244 PG_FREE_IF_COPY(query
, 0);
245 PG_FREE_IF_COPY(ex
, 1);
247 PG_RETURN_BOOL(false);
252 for (i
= 0; i
< ex
->size
; i
++)
254 iq
= GETQUERY(query
);
255 if (ie
[i
].type
!= QI_VAL
)
257 for (j
= 0; j
< query
->size
; j
++)
258 if (iq
[j
].type
== QI_VAL
&& ie
[i
].operand
.valcrc
== iq
[j
].operand
.valcrc
)
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);
279 tsq_mcontained(PG_FUNCTION_ARGS
)