aboutsummaryrefslogtreecommitdiff
path: root/contrib/tsearch2/query_support.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tsearch2/query_support.c')
-rw-r--r--contrib/tsearch2/query_support.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/contrib/tsearch2/query_support.c b/contrib/tsearch2/query_support.c
index c973def7d4d..edc2d48fcfb 100644
--- a/contrib/tsearch2/query_support.c
+++ b/contrib/tsearch2/query_support.c
@@ -14,6 +14,117 @@ tsquery_numnode(PG_FUNCTION_ARGS) {
PG_RETURN_INT32(nnode);
}
+static QTNode*
+join_tsqueries(QUERYTYPE *a, QUERYTYPE *b) {
+ QTNode *res=(QTNode*)palloc0( sizeof(QTNode) );
+
+ res->flags |= QTN_NEEDFREE;
+
+ res->valnode = (ITEM*)palloc0( sizeof(ITEM) );
+ res->valnode->type = OPR;
+
+ res->child = (QTNode**)palloc0( sizeof(QTNode*)*2 );
+ res->child[0] = QT2QTN( GETQUERY(b), GETOPERAND(b) );
+ res->child[1] = QT2QTN( GETQUERY(a), GETOPERAND(a) );
+ res->nchild = 2;
+
+ return res;
+}
+
+PG_FUNCTION_INFO_V1(tsquery_and);
+Datum tsquery_and(PG_FUNCTION_ARGS);
+
+Datum
+tsquery_and(PG_FUNCTION_ARGS) {
+ QUERYTYPE *a = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
+ QUERYTYPE *b = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
+ QTNode *res;
+ QUERYTYPE *query;
+
+ if ( a->size == 0 ) {
+ PG_FREE_IF_COPY(a,1);
+ PG_RETURN_POINTER(b);
+ } else if ( b->size == 0 ) {
+ PG_FREE_IF_COPY(b,1);
+ PG_RETURN_POINTER(a);
+ }
+
+ res = join_tsqueries(a, b);
+
+ res->valnode->val = '&';
+
+ query = QTN2QT( res, PlainMemory );
+
+ QTNFree(res);
+ PG_FREE_IF_COPY(a,0);
+ PG_FREE_IF_COPY(b,1);
+
+ PG_RETURN_POINTER(query);
+}
+
+PG_FUNCTION_INFO_V1(tsquery_or);
+Datum tsquery_or(PG_FUNCTION_ARGS);
+
+Datum
+tsquery_or(PG_FUNCTION_ARGS) {
+ QUERYTYPE *a = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
+ QUERYTYPE *b = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
+ QTNode *res;
+ QUERYTYPE *query;
+
+ if ( a->size == 0 ) {
+ PG_FREE_IF_COPY(a,1);
+ PG_RETURN_POINTER(b);
+ } else if ( b->size == 0 ) {
+ PG_FREE_IF_COPY(b,1);
+ PG_RETURN_POINTER(a);
+ }
+
+ res = join_tsqueries(a, b);
+
+ res->valnode->val = '|';
+
+ query = QTN2QT( res, PlainMemory );
+
+ QTNFree(res);
+ PG_FREE_IF_COPY(a,0);
+ PG_FREE_IF_COPY(b,1);
+
+ PG_RETURN_POINTER(query);
+}
+
+PG_FUNCTION_INFO_V1(tsquery_not);
+Datum tsquery_not(PG_FUNCTION_ARGS);
+
+Datum
+tsquery_not(PG_FUNCTION_ARGS) {
+ QUERYTYPE *a = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
+ QTNode *res;
+ QUERYTYPE *query;
+
+ if ( a->size == 0 )
+ PG_RETURN_POINTER(a);
+
+ res=(QTNode*)palloc0( sizeof(QTNode) );
+
+ res->flags |= QTN_NEEDFREE;
+
+ res->valnode = (ITEM*)palloc0( sizeof(ITEM) );
+ res->valnode->type = OPR;
+ res->valnode->val = '!';
+
+ res->child = (QTNode**)palloc0( sizeof(QTNode*) );
+ res->child[0] = QT2QTN( GETQUERY(a), GETOPERAND(a) );
+ res->nchild = 1;
+
+ query = QTN2QT( res, PlainMemory );
+
+ QTNFree(res);
+ PG_FREE_IF_COPY(a,0);
+
+ PG_RETURN_POINTER(query);
+}
+
static int
CompareTSQ( QUERYTYPE *a, QUERYTYPE *b ) {
if ( a->size != b->size ) {