Commit 19d29015 authored by Teodor Sigaev's avatar Teodor Sigaev

Fix nested NOT operation cleanup in tsquery.

During normalization of tsquery tree it tries to simplify nested NOT
operations but there it's obvioulsy missed that subsequent node could be
a leaf node (value node)

Bug #14245: Segfault on weird to_tsquery
Reported by David Kellum.
parent ce150e7e
...@@ -406,6 +406,8 @@ normalize_phrase_tree(NODE *node) ...@@ -406,6 +406,8 @@ normalize_phrase_tree(NODE *node)
if (node->valnode->qoperator.oper == OP_NOT) if (node->valnode->qoperator.oper == OP_NOT)
{ {
NODE *orignode = node;
/* eliminate NOT sequence */ /* eliminate NOT sequence */
while (node->valnode->type == QI_OPR && while (node->valnode->type == QI_OPR &&
node->valnode->qoperator.oper == node->right->valnode->qoperator.oper) node->valnode->qoperator.oper == node->right->valnode->qoperator.oper)
...@@ -413,6 +415,10 @@ normalize_phrase_tree(NODE *node) ...@@ -413,6 +415,10 @@ normalize_phrase_tree(NODE *node)
node = node->right->right; node = node->right->right;
} }
if (orignode != node)
/* current node isn't checked yet */
node = normalize_phrase_tree(node);
else
node->right = normalize_phrase_tree(node->right); node->right = normalize_phrase_tree(node->right);
} }
else if (node->valnode->qoperator.oper == OP_PHRASE) else if (node->valnode->qoperator.oper == OP_PHRASE)
......
...@@ -555,6 +555,18 @@ SELECT plainto_tsquery('english', 'foo bar') && 'asd | fg'; ...@@ -555,6 +555,18 @@ SELECT plainto_tsquery('english', 'foo bar') && 'asd | fg';
(1 row) (1 row)
-- Check stop word deletion, a and s are stop-words -- Check stop word deletion, a and s are stop-words
SELECT to_tsquery('english', '!(a & !b) & c');
to_tsquery
------------
'b' & 'c'
(1 row)
SELECT to_tsquery('english', '!(a & !b)');
to_tsquery
------------
'b'
(1 row)
SELECT to_tsquery('english', '(1 <-> 2) <-> a'); SELECT to_tsquery('english', '(1 <-> 2) <-> a');
to_tsquery to_tsquery
------------- -------------
......
...@@ -130,6 +130,9 @@ SELECT plainto_tsquery('english', 'foo bar') || !!plainto_tsquery('english', 'as ...@@ -130,6 +130,9 @@ SELECT plainto_tsquery('english', 'foo bar') || !!plainto_tsquery('english', 'as
SELECT plainto_tsquery('english', 'foo bar') && 'asd | fg'; SELECT plainto_tsquery('english', 'foo bar') && 'asd | fg';
-- Check stop word deletion, a and s are stop-words -- Check stop word deletion, a and s are stop-words
SELECT to_tsquery('english', '!(a & !b) & c');
SELECT to_tsquery('english', '!(a & !b)');
SELECT to_tsquery('english', '(1 <-> 2) <-> a'); SELECT to_tsquery('english', '(1 <-> 2) <-> a');
SELECT to_tsquery('english', '(1 <-> a) <-> 2'); SELECT to_tsquery('english', '(1 <-> a) <-> 2');
SELECT to_tsquery('english', '(a <-> 1) <-> 2'); SELECT to_tsquery('english', '(a <-> 1) <-> 2');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment