mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-26 17:41:59 +00:00
Avoid exponential backtracking in parser, part 2
This commit is contained in:
parent
1813e7ad35
commit
5ba42d690c
@ -754,7 +754,10 @@ bool ParserFunction::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
has_all = true;
|
||||
|
||||
if (has_all && has_distinct)
|
||||
{
|
||||
pos.noBacktrackOnFailure();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (has_all || has_distinct)
|
||||
{
|
||||
@ -772,11 +775,17 @@ bool ParserFunction::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
|
||||
const char * contents_begin = pos->begin;
|
||||
if (!contents.parse(pos, expr_list_args, expected))
|
||||
{
|
||||
pos.noBacktrackOnFailure();
|
||||
return false;
|
||||
}
|
||||
const char * contents_end = pos->begin;
|
||||
|
||||
if (pos->type != TokenType::ClosingRoundBracket)
|
||||
{
|
||||
pos.noBacktrackOnFailure();
|
||||
return false;
|
||||
}
|
||||
++pos;
|
||||
|
||||
/** Check for a common error case - often due to the complexity of quoting command-line arguments,
|
||||
@ -809,7 +818,10 @@ bool ParserFunction::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
|
||||
/// Parametric aggregate functions cannot have DISTINCT in parameters list.
|
||||
if (has_distinct)
|
||||
{
|
||||
pos.noBacktrackOnFailure();
|
||||
return false;
|
||||
}
|
||||
|
||||
expr_list_params = expr_list_args;
|
||||
expr_list_args = nullptr;
|
||||
@ -827,7 +839,10 @@ bool ParserFunction::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
has_all = true;
|
||||
|
||||
if (has_all && has_distinct)
|
||||
{
|
||||
pos.noBacktrackOnFailure();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (has_all || has_distinct)
|
||||
{
|
||||
@ -841,10 +856,16 @@ bool ParserFunction::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
}
|
||||
|
||||
if (!contents.parse(pos, expr_list_args, expected))
|
||||
{
|
||||
pos.noBacktrackOnFailure();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pos->type != TokenType::ClosingRoundBracket)
|
||||
{
|
||||
pos.noBacktrackOnFailure();
|
||||
return false;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
|
||||
@ -878,6 +899,7 @@ bool ParserFunction::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
ParserFilterClause filter_parser;
|
||||
if (!filter_parser.parse(pos, function_node_as_iast, expected))
|
||||
{
|
||||
pos.noBacktrackOnFailure();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -891,6 +913,7 @@ bool ParserFunction::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
ParserWindowReference window_reference;
|
||||
if (!window_reference.parse(pos, function_node_as_iast, expected))
|
||||
{
|
||||
pos.noBacktrackOnFailure();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ public:
|
||||
{
|
||||
uint32_t depth = 0;
|
||||
uint32_t max_depth = 0;
|
||||
bool no_backtrack_on_failure = false;
|
||||
|
||||
Pos(Tokens & tokens_, uint32_t max_depth_) : TokenIterator(tokens_), max_depth(max_depth_) {}
|
||||
|
||||
@ -77,6 +78,11 @@ public:
|
||||
throw Exception("Logical error in parser: incorrect calculation of parse depth", ErrorCodes::LOGICAL_ERROR);
|
||||
--depth;
|
||||
}
|
||||
|
||||
void noBacktrackOnFailure()
|
||||
{
|
||||
no_backtrack_on_failure = true;
|
||||
}
|
||||
};
|
||||
|
||||
/** Get the text of this parser parses. */
|
||||
|
@ -6,6 +6,9 @@ namespace DB
|
||||
|
||||
bool IParserBase::parse(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
{
|
||||
if (pos.no_backtrack_on_failure)
|
||||
return false;
|
||||
|
||||
expected.add(pos, getName());
|
||||
|
||||
return wrapParseImpl(pos, IncreaseDepthTag{}, [&]
|
||||
|
@ -16,7 +16,7 @@ public:
|
||||
{
|
||||
Pos begin = pos;
|
||||
bool res = func();
|
||||
if (!res)
|
||||
if (!res && !pos.no_backtrack_on_failure)
|
||||
pos = begin;
|
||||
return res;
|
||||
}
|
||||
@ -30,7 +30,7 @@ public:
|
||||
pos.increaseDepth();
|
||||
bool res = func();
|
||||
pos.decreaseDepth();
|
||||
if (!res)
|
||||
if (!res && !pos.no_backtrack_on_failure)
|
||||
pos = begin;
|
||||
return res;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user