diff options
author | Teodor Sigaev <teodor@sigaev.ru> | 2016-06-27 20:55:24 +0300 |
---|---|---|
committer | Teodor Sigaev <teodor@sigaev.ru> | 2016-06-27 20:55:24 +0300 |
commit | 6734a1cacd44f5b731933cbc93182b135b167d0c (patch) | |
tree | 39b868e9a39f4301c7c9699b82f95f5979acb590 /src/backend/utils/adt/tsquery_cleanup.c | |
parent | 3dbbd0f02a257d8d5c4cba14726371505f2e7266 (diff) | |
download | postgresql-6734a1cacd44f5b731933cbc93182b135b167d0c.tar.gz postgresql-6734a1cacd44f5b731933cbc93182b135b167d0c.zip |
Change predecence of phrase operator.
<-> operator now have higher predecence than & (AND) operator. This change
was motivated by unexpected difference of similar queries:
'a & b <-> c'::tsquery and 'b <-> c & a'. Before first query means
(a & b) <-> c and second one - '(b <-> c) & a', now phrase operator evaluates
first.
Per suggestion from Tom Lane 32260.1465402409@sss.pgh.pa.us
Diffstat (limited to 'src/backend/utils/adt/tsquery_cleanup.c')
-rw-r--r-- | src/backend/utils/adt/tsquery_cleanup.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/src/backend/utils/adt/tsquery_cleanup.c b/src/backend/utils/adt/tsquery_cleanup.c index 6c74070e45e..1a90964ce79 100644 --- a/src/backend/utils/adt/tsquery_cleanup.c +++ b/src/backend/utils/adt/tsquery_cleanup.c @@ -25,11 +25,18 @@ typedef struct NODE QueryItem *valnode; } NODE; -/* Non-operator nodes have fake (but highest) priority */ +/* + * To simplify walking on query tree and pushing down of phrase operator + * we define some fake priority here: phrase operator has highest priority + * of any other operators (and we believe here that OP_PHRASE is a highest + * code of operations) and value node has ever highest priority. + * Priority values of other operations don't matter until they are less than + * phrase operator and value node. + */ +#define VALUE_PRIORITY (OP_COUNT + 1) #define NODE_PRIORITY(x) \ ( ((x)->valnode->qoperator.type == QI_OPR) ? \ - QO_PRIORITY((x)->valnode) : \ - TOP_PRIORITY ) + (x)->valnode->qoperator.oper : VALUE_PRIORITY ) /* * make query tree from plain view of query @@ -416,6 +423,10 @@ normalize_phrase_tree(NODE *node) node->left = normalize_phrase_tree(node->left); node->right = normalize_phrase_tree(node->right); + /* + * if subtree contains only nodes with higher "priority" then + * we are done. See comment near NODE_PRIORITY() + */ if (NODE_PRIORITY(node) <= NODE_PRIORITY(node->right) && NODE_PRIORITY(node) <= NODE_PRIORITY(node->left)) return node; |