]> granicus.if.org Git - postgresql/commitdiff
Restore original tsquery operation numbering.
authorTeodor Sigaev <teodor@sigaev.ru>
Fri, 8 Apr 2016 17:11:30 +0000 (20:11 +0300)
committerTeodor Sigaev <teodor@sigaev.ru>
Fri, 8 Apr 2016 17:11:30 +0000 (20:11 +0300)
As noticed by Tom Lane changing operation's number in commit
bb140506df605fab58f48926ee1db1f80bdafb59 causes on-disk format incompatibility.
Revert to previous numbering, that is reason to add special array to store
priorities of operation. Also it reverts order of tsquery to previous.

Author: Dmitry Ivanov

src/backend/utils/adt/tsquery.c
src/include/tsearch/ts_type.h
src/test/regress/expected/tsearch.out
src/test/regress/expected/tstypes.out

index 257b5d33456910aaf0c7496d407197ce0995515f..eea6e0eae1730c6a66d4b467ff257bacb1e92ac0 100644 (file)
 
 #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
index ff3fef1f472c8006923b983e5c7aff8cd797909d..8d24b32fac1773e69c4ad3267ddad004640e1f71 100644 (file)
@@ -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
 {
index a4c61e20cb6ed4987e5d00aa989ac554dc4f7e84..2c3aa1a2937fb746fd3dcba4b67fc0ed267e2038 100644 (file)
@@ -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;
index c904c1c7054d5b33bff23223213ce98075dc1f4f..c8ca0624d439e89ad36342db029c3c8e3b0ccc98 100644 (file)
@@ -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";