aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/tsquery.c12
-rw-r--r--src/include/tsearch/ts_type.h17
-rw-r--r--src/test/regress/expected/tsearch.out14
-rw-r--r--src/test/regress/expected/tstypes.out2
4 files changed, 30 insertions, 15 deletions
diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c
index 257b5d33456..eea6e0eae17 100644
--- a/src/backend/utils/adt/tsquery.c
+++ b/src/backend/utils/adt/tsquery.c
@@ -16,12 +16,21 @@
#include "libpq/pqformat.h"
#include "miscadmin.h"
+#include "tsearch/ts_type.h"
#include "tsearch/ts_locale.h"
#include "tsearch/ts_utils.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
#include "utils/pg_crc.h"
+/* FTS operator priorities, see ts_type.h */
+const int tsearch_op_priority[OP_COUNT] =
+{
+ 3, /* OP_NOT */
+ 2, /* OP_AND */
+ 1, /* OP_OR */
+ 4 /* OP_PHRASE */
+};
struct TSQueryParserStateData
{
@@ -736,9 +745,6 @@ while( ( (inf)->cur - (inf)->buf ) + (addsize) + 1 >= (inf)->buflen ) \
(inf)->cur = (inf)->buf + len; \
}
-#define PRINT_PRIORITY(x) \
- ( (QO_PRIORITY(x) == OP_NOT) ? OP_NOT_PHRASE : QO_PRIORITY(x) )
-
/*
* recursively traverse the tree and
* print it in infix (human-readable) form
diff --git a/src/include/tsearch/ts_type.h b/src/include/tsearch/ts_type.h
index ff3fef1f472..8d24b32fac1 100644
--- a/src/include/tsearch/ts_type.h
+++ b/src/include/tsearch/ts_type.h
@@ -222,11 +222,15 @@ typedef struct
* for query transformation! That's need to simplify
* algorithm of query transformation.
*/
-#define OP_OR 1
+#define OP_NOT 1
#define OP_AND 2
-#define OP_NOT 3
+#define OP_OR 3
#define OP_PHRASE 4
-#define OP_NOT_PHRASE 5 /*
+#define OP_COUNT 4
+
+extern const int tsearch_op_priority[OP_COUNT];
+
+#define NOT_PHRASE_P 5 /*
* OP_PHRASE negation operations must have greater
* priority in order to force infix() to surround
* the whole OP_PHRASE expression with parentheses.
@@ -234,8 +238,13 @@ typedef struct
#define TOP_PRIORITY 6 /* highest priority for val nodes */
-#define OP_PRIORITY(x) (x)
+/* get operation priority by its code*/
+#define OP_PRIORITY(x) ( tsearch_op_priority[(x) - 1] )
+/* get QueryOperator priority */
#define QO_PRIORITY(x) OP_PRIORITY(((QueryOperator *) (x))->oper)
+/* special case: get QueryOperator priority for correct printing !(a <-> b>) */
+#define PRINT_PRIORITY(x) \
+ ( (((QueryOperator *) (x))->oper == OP_NOT) ? NOT_PHRASE_P : QO_PRIORITY(x) )
typedef struct
{
diff --git a/src/test/regress/expected/tsearch.out b/src/test/regress/expected/tsearch.out
index a4c61e20cb6..2c3aa1a2937 100644
--- a/src/test/regress/expected/tsearch.out
+++ b/src/test/regress/expected/tsearch.out
@@ -1169,7 +1169,7 @@ RESET enable_seqscan;
SELECT ts_rewrite('foo & bar & qq & new & york', 'new & york'::tsquery, 'big & apple | nyc | new & york & city');
ts_rewrite
------------------------------------------------------------------------------
- 'foo' & 'bar' & 'qq' & ( 'nyc' | 'big' & 'apple' | 'city' & 'new' & 'york' )
+ 'foo' & 'bar' & 'qq' & ( 'city' & 'new' & 'york' | 'nyc' | 'big' & 'apple' )
(1 row)
SELECT ts_rewrite('moscow', 'SELECT keyword, sample FROM test_tsquery'::text );
@@ -1187,7 +1187,7 @@ SELECT ts_rewrite('moscow & hotel', 'SELECT keyword, sample FROM test_tsquery'::
SELECT ts_rewrite('bar & new & qq & foo & york', 'SELECT keyword, sample FROM test_tsquery'::text );
ts_rewrite
---------------------------------------------------------------------------------
- ( 'nyc' | 'big' & 'appl' | 'new' & 'york' ) & 'citi' & 'foo' & ( 'bar' | 'qq' )
+ 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | 'big' & 'appl' | 'new' & 'york' )
(1 row)
SELECT ts_rewrite( 'moscow', 'SELECT keyword, sample FROM test_tsquery');
@@ -1205,7 +1205,7 @@ SELECT ts_rewrite( 'moscow & hotel', 'SELECT keyword, sample FROM test_tsquery')
SELECT ts_rewrite( 'bar & new & qq & foo & york', 'SELECT keyword, sample FROM test_tsquery');
ts_rewrite
---------------------------------------------------------------------------------
- ( 'nyc' | 'big' & 'appl' | 'new' & 'york' ) & 'citi' & 'foo' & ( 'bar' | 'qq' )
+ 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | 'big' & 'appl' | 'new' & 'york' )
(1 row)
SELECT ts_rewrite('1 & (2 <-> 3)', 'SELECT keyword, sample FROM test_tsquery'::text );
@@ -1270,7 +1270,7 @@ SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_t
SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & new & qq & foo & york') AS query;
ts_rewrite
---------------------------------------------------------------------------------
- ( 'nyc' | 'big' & 'appl' | 'new' & 'york' ) & 'citi' & 'foo' & ( 'bar' | 'qq' )
+ 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | 'big' & 'appl' | 'new' & 'york' )
(1 row)
SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query;
@@ -1288,7 +1288,7 @@ SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_t
SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & new & qq & foo & york') AS query;
ts_rewrite
---------------------------------------------------------------------------------
- ( 'nyc' | 'big' & 'appl' | 'new' & 'york' ) & 'citi' & 'foo' & ( 'bar' | 'qq' )
+ 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | 'big' & 'appl' | 'new' & 'york' )
(1 row)
CREATE INDEX qq ON test_tsquery USING gist (keyword tsquery_ops);
@@ -1331,7 +1331,7 @@ SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_t
SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & new & qq & foo & york') AS query;
ts_rewrite
---------------------------------------------------------------------------------
- ( 'nyc' | 'big' & 'appl' | 'new' & 'york' ) & 'citi' & 'foo' & ( 'bar' | 'qq' )
+ 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | 'big' & 'appl' | 'new' & 'york' )
(1 row)
SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query;
@@ -1349,7 +1349,7 @@ SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_t
SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & new & qq & foo & york') AS query;
ts_rewrite
---------------------------------------------------------------------------------
- ( 'nyc' | 'big' & 'appl' | 'new' & 'york' ) & 'citi' & 'foo' & ( 'bar' | 'qq' )
+ 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | 'big' & 'appl' | 'new' & 'york' )
(1 row)
RESET enable_seqscan;
diff --git a/src/test/regress/expected/tstypes.out b/src/test/regress/expected/tstypes.out
index c904c1c7054..c8ca0624d43 100644
--- a/src/test/regress/expected/tstypes.out
+++ b/src/test/regress/expected/tstypes.out
@@ -473,7 +473,7 @@ SELECT 'a' > 'b & c'::tsquery as "false";
SELECT 'a | f' < 'b & c'::tsquery as "false";
false
-------
- f
+ t
(1 row)
SELECT 'a | ff' < 'b & c'::tsquery as "false";