From 6734a1cacd44f5b731933cbc93182b135b167d0c Mon Sep 17 00:00:00 2001 From: Teodor Sigaev Date: Mon, 27 Jun 2016 20:55:24 +0300 Subject: 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 --- src/backend/utils/adt/tsquery_cleanup.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'src/backend/utils/adt/tsquery_cleanup.c') 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; -- cgit v1.2.3