From 61366a950374ccbbd972288282eb203229b474de Mon Sep 17 00:00:00 2001
From: Teodor Sigaev <teodor@sigaev.ru>
Date: Thu, 28 Aug 2003 12:23:24 +0000
Subject: [PATCH] More accuracy works with stopwords in queries

---
 contrib/tsearch2/expected/tsearch2.out | 24 ++++++++++++
 contrib/tsearch2/query.c               | 13 +------
 contrib/tsearch2/query.h               |  3 +-
 contrib/tsearch2/rewrite.c             | 51 ++++----------------------
 contrib/tsearch2/sql/tsearch2.sql      |  4 ++
 5 files changed, 39 insertions(+), 56 deletions(-)

diff --git a/contrib/tsearch2/expected/tsearch2.out b/contrib/tsearch2/expected/tsearch2.out
index d0b91043539..8571e59bbb1 100644
--- a/contrib/tsearch2/expected/tsearch2.out
+++ b/contrib/tsearch2/expected/tsearch2.out
@@ -569,6 +569,30 @@ select to_tsquery('default', '\'the wether\':dc & \'           sKies \':BC ');
  'wether':CD & 'sky':BC
 (1 row)
 
+select to_tsquery('asd&(and|fghj)');
+   to_tsquery   
+----------------
+ 'asd' & 'fghj'
+(1 row)
+
+select to_tsquery('(asd&and)|fghj');
+   to_tsquery   
+----------------
+ 'asd' | 'fghj'
+(1 row)
+
+select to_tsquery('(asd&!and)|fghj');
+   to_tsquery   
+----------------
+ 'asd' | 'fghj'
+(1 row)
+
+select to_tsquery('(the|and&(i&1))&fghj');
+  to_tsquery  
+--------------
+ '1' & 'fghj'
+(1 row)
+
 select 'a b:89  ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca';
  ?column? 
 ----------
diff --git a/contrib/tsearch2/query.c b/contrib/tsearch2/query.c
index 0019b04f166..00537f4170e 100644
--- a/contrib/tsearch2/query.c
+++ b/contrib/tsearch2/query.c
@@ -52,15 +52,6 @@ Datum		to_tsquery_name(PG_FUNCTION_ARGS);
 PG_FUNCTION_INFO_V1(to_tsquery_current);
 Datum		to_tsquery_current(PG_FUNCTION_ARGS);
 
-#define END			0
-#define ERR			1
-#define VAL			2
-#define OPR			3
-#define OPEN		4
-#define CLOSE		5
-#define VALTRUE		6			/* for stop words */
-#define VALFALSE	7
-
 /* parser's states */
 #define WAITOPERAND 1
 #define WAITOPERATOR	2
@@ -293,7 +284,7 @@ pushval_morph(QPRS_STATE * state, int typeval, char *strval, int lenval, int2 we
 
 	/* XXX */
 	if (prs.curwords == 0)
-		pushval_asis(state, VALTRUE, 0, 0, 0);
+		pushval_asis(state, VALSTOP, 0, 0, 0);
 }
 
 #define STACKDEPTH	32
@@ -526,7 +517,7 @@ findoprnd(ITEM * ptr, int4 *pos)
 	elog(DEBUG3, (ptr[*pos].type == OPR) ?
 		 "%d  %c" : "%d  %d", *pos, ptr[*pos].val);
 #endif
-	if (ptr[*pos].type == VAL || ptr[*pos].type == VALTRUE)
+	if (ptr[*pos].type == VAL || ptr[*pos].type == VALSTOP)
 	{
 		ptr[*pos].left = 0;
 		(*pos)++;
diff --git a/contrib/tsearch2/query.h b/contrib/tsearch2/query.h
index 4a79efdc539..a65dbca762f 100644
--- a/contrib/tsearch2/query.h
+++ b/contrib/tsearch2/query.h
@@ -46,8 +46,7 @@ typedef struct
 #define OPR				3
 #define OPEN			4
 #define CLOSE			5
-#define VALTRUE			6		/* for stop words */
-#define VALFALSE		7
+#define VALSTOP			6		/* for stop words */
 
 bool TS_execute(ITEM * curitem, void *checkval,
 		   bool calcnot, bool (*chkcond) (void *checkval, ITEM * val));
diff --git a/contrib/tsearch2/rewrite.c b/contrib/tsearch2/rewrite.c
index ac42f2c9a94..4d7294cd74a 100644
--- a/contrib/tsearch2/rewrite.c
+++ b/contrib/tsearch2/rewrite.c
@@ -177,6 +177,7 @@ clean_NOT_v2(ITEM * ptr, int4 *len)
 #define V_UNKNOWN	0
 #define V_TRUE		1
 #define V_FALSE		2
+#define V_STOP		3
 
 /*
  * Clean query tree from values which is always in
@@ -190,10 +191,10 @@ clean_fakeval_intree(NODE * node, char *result)
 
 	if (node->valnode->type == VAL)
 		return node;
-	else if (node->valnode->type == VALTRUE)
+	else if (node->valnode->type == VALSTOP)
 	{
 		pfree(node);
-		*result = V_TRUE;
+		*result = V_STOP;
 		return NULL;
 	}
 
@@ -203,65 +204,29 @@ clean_fakeval_intree(NODE * node, char *result)
 		node->right = clean_fakeval_intree(node->right, &rresult);
 		if (!node->right)
 		{
-			*result = (rresult == V_TRUE) ? V_FALSE : V_TRUE;
+			*result = V_STOP;
 			freetree(node);
 			return NULL;
 		}
 	}
-	else if (node->valnode->val == (int4) '|')
-	{
-		NODE	   *res = node;
-
-		node->left = clean_fakeval_intree(node->left, &lresult);
-		node->right = clean_fakeval_intree(node->right, &rresult);
-		if (lresult == V_TRUE || rresult == V_TRUE)
-		{
-			freetree(node);
-			*result = V_TRUE;
-			return NULL;
-		}
-		else if (lresult == V_FALSE && rresult == V_FALSE)
-		{
-			freetree(node);
-			*result = V_FALSE;
-			return NULL;
-		}
-		else if (lresult == V_FALSE)
-		{
-			res = node->right;
-			pfree(node);
-		}
-		else if (rresult == V_FALSE)
-		{
-			res = node->left;
-			pfree(node);
-		}
-		return res;
-	}
 	else
 	{
 		NODE	   *res = node;
 
 		node->left = clean_fakeval_intree(node->left, &lresult);
 		node->right = clean_fakeval_intree(node->right, &rresult);
-		if (lresult == V_FALSE || rresult == V_FALSE)
-		{
-			freetree(node);
-			*result = V_FALSE;
-			return NULL;
-		}
-		else if (lresult == V_TRUE && rresult == V_TRUE)
+		if (lresult == V_STOP && rresult == V_STOP)
 		{
 			freetree(node);
-			*result = V_TRUE;
+			*result = V_STOP;
 			return NULL;
 		}
-		else if (lresult == V_TRUE)
+		else if (lresult == V_STOP)
 		{
 			res = node->right;
 			pfree(node);
 		}
-		else if (rresult == V_TRUE)
+		else if (rresult == V_STOP)
 		{
 			res = node->left;
 			pfree(node);
diff --git a/contrib/tsearch2/sql/tsearch2.sql b/contrib/tsearch2/sql/tsearch2.sql
index 0c10edb6ec9..d4f1021d7d8 100644
--- a/contrib/tsearch2/sql/tsearch2.sql
+++ b/contrib/tsearch2/sql/tsearch2.sql
@@ -87,6 +87,10 @@ SELECT length(to_tsvector('default', '345 qwe@efd.r \' http://www.com/ http://ae
 select to_tsquery('default', 'qwe & sKies '); 
 select to_tsquery('simple', 'qwe & sKies '); 
 select to_tsquery('default', '\'the wether\':dc & \'           sKies \':BC ');
+select to_tsquery('asd&(and|fghj)');
+select to_tsquery('(asd&and)|fghj');
+select to_tsquery('(asd&!and)|fghj');
+select to_tsquery('(the|and&(i&1))&fghj');
 select 'a b:89  ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca';
 select 'a b:89  ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:B';
 select 'a b:89  ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:A';
-- 
GitLab