mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
dbms: fixed error; parsing 'ON' expression in JOINs [#METR-18692].
This commit is contained in:
parent
ffa33eea3d
commit
52a3b686cd
@ -42,6 +42,7 @@ public:
|
||||
|
||||
ASTPtr table; /// "Правая" таблица для соединения - подзапрос или имя таблицы.
|
||||
ASTPtr using_expr_list; /// По каким столбцам выполнять соединение.
|
||||
ASTPtr on_expr; /// Условие соединения. Поддерживается либо USING либо ON, но не одновременно.
|
||||
|
||||
ASTJoin() = default;
|
||||
ASTJoin(const StringRange range_) : IAST(range_) {}
|
||||
@ -108,11 +109,16 @@ protected:
|
||||
|
||||
table->formatImpl(settings, state, frame);
|
||||
|
||||
if (kind != ASTJoin::Cross)
|
||||
if (using_expr_list)
|
||||
{
|
||||
settings.ostr << (settings.hilite ? hilite_keyword : "") << " USING " << (settings.hilite ? hilite_none : "");
|
||||
using_expr_list->formatImpl(settings, state, frame);
|
||||
}
|
||||
else if (on_expr)
|
||||
{
|
||||
settings.ostr << (settings.hilite ? hilite_keyword : "") << " ON " << (settings.hilite ? hilite_none : "");
|
||||
on_expr->formatImpl(settings, state, frame);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -28,8 +28,10 @@ bool ParserJoin::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_p
|
||||
ParserString s_outer("OUTER", true, true);
|
||||
ParserString s_join("JOIN", true, true);
|
||||
ParserString s_using("USING", true, true);
|
||||
ParserString s_on("ON", true, true);
|
||||
|
||||
ParserNotEmptyExpressionList exp_list(false);
|
||||
ParserLogicalOrExpression exp_elem;
|
||||
ParserWithOptionalAlias subquery(ParserPtr(new ParserSubquery), true);
|
||||
ParserIdentifier identifier;
|
||||
|
||||
@ -93,15 +95,41 @@ bool ParserJoin::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_p
|
||||
|
||||
if (join->kind != ASTJoin::Cross)
|
||||
{
|
||||
if (!s_using.ignore(pos, end, max_parsed_pos, expected))
|
||||
if (s_using.ignore(pos, end, max_parsed_pos, expected))
|
||||
{
|
||||
ws.ignore(pos, end);
|
||||
|
||||
/// Выражение для USING можно указать как в скобках, так и без них.
|
||||
bool in_parens = ParserString("(").ignore(pos, end);
|
||||
if (in_parens)
|
||||
ws.ignore(pos, end);
|
||||
|
||||
if (!exp_list.parse(pos, end, join->using_expr_list, max_parsed_pos, expected))
|
||||
return false;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
|
||||
if (in_parens)
|
||||
{
|
||||
ws.ignore(pos, end);
|
||||
if (!ParserString(")").ignore(pos, end))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (s_on.ignore(pos, end, max_parsed_pos, expected))
|
||||
{
|
||||
ws.ignore(pos, end);
|
||||
|
||||
if (!exp_elem.parse(pos, end, join->on_expr, max_parsed_pos, expected))
|
||||
return false;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
}
|
||||
else
|
||||
{
|
||||
expected = "USING or ON";
|
||||
return false;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
|
||||
if (!exp_list.parse(pos, end, join->using_expr_list, max_parsed_pos, expected))
|
||||
return false;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
}
|
||||
}
|
||||
|
||||
join->children.push_back(join->table);
|
||||
|
@ -113,6 +113,9 @@ bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_p
|
||||
if (s_dot.ignore(pos, end, max_parsed_pos, expected))
|
||||
{
|
||||
select_query->database = select_query->table;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
|
||||
if (!ident.parse(pos, end, select_query->table, max_parsed_pos, expected))
|
||||
return false;
|
||||
|
||||
|
@ -0,0 +1,2 @@
|
||||
0
|
||||
0
|
@ -0,0 +1,2 @@
|
||||
SELECT * FROM system . one;
|
||||
SELECT * FROM system /* Hello */. `one`;
|
Loading…
Reference in New Issue
Block a user