dbms: fixed error; parsing 'ON' expression in JOINs [#METR-18692].

This commit is contained in:
Alexey Milovidov 2015-11-08 05:42:33 +03:00
parent ffa33eea3d
commit 52a3b686cd
5 changed files with 50 additions and 9 deletions

View File

@ -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);
}
}
};

View File

@ -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);

View File

@ -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;

View File

@ -0,0 +1,2 @@
SELECT * FROM system . one;
SELECT * FROM system /* Hello */. `one`;