diff --git a/dbms/src/Parsers/ExpressionListParsers.cpp b/dbms/src/Parsers/ExpressionListParsers.cpp index 404f25cd14b..0fc7ab7fead 100644 --- a/dbms/src/Parsers/ExpressionListParsers.cpp +++ b/dbms/src/Parsers/ExpressionListParsers.cpp @@ -375,6 +375,37 @@ bool ParserPrefixUnaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr & ws.ignore(pos, end); + /// Позволяем парсить цепочки вида NOT NOT x. Это хак. + /** Так сделано, потому что среди унарных операторов есть только минус и NOT. + * Но для минуса цепочку из унарных операторов не требуется поддерживать. + */ + if (it[0] && 0 == strncmp(it[0], "NOT", 3)) + { + /// Было ли чётное количество NOT. + bool even = false; + + const char ** jt; + while (true) + { + for (jt = operators; *jt; jt += 2) + { + ParserString op(jt[0], true, true); + if (op.ignore(pos, end, max_parsed_pos, expected)) + break; + } + + if (!*jt) + break; + + even = !even; + + ws.ignore(pos, end); + } + + if (even) + it = jt; /// Зануляем результат парсинга первого NOT. Получается, как будто цепочки NOT нет вообще. + } + ASTPtr elem; if (!elem_parser->parse(pos, end, elem, max_parsed_pos, expected)) return false; diff --git a/dbms/tests/queries/0_stateless/00164_not_chain.reference b/dbms/tests/queries/0_stateless/00164_not_chain.reference new file mode 100644 index 00000000000..ac8d6d16066 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00164_not_chain.reference @@ -0,0 +1,5 @@ +0 +1 +0 +1 +0 diff --git a/dbms/tests/queries/0_stateless/00164_not_chain.sql b/dbms/tests/queries/0_stateless/00164_not_chain.sql new file mode 100644 index 00000000000..39fe8724e33 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00164_not_chain.sql @@ -0,0 +1,5 @@ +SELECT NOT 1; +SELECT NOT NOT 1; +SELECT NOT NOT NOT 1; +SELECT NOT NOT NOT NOT 1 = 1; +SELECT NOT NOT not NoT NOT 1 = 1;