ClickHouse/src/Parsers/ParserTablesInSelectQuery.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

278 lines
9.2 KiB
C++
Raw Normal View History

#include <Parsers/CommonParsers.h>
#include <Parsers/ExpressionElementParsers.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/ASTFunction.h>
#include <Parsers/ASTTablesInSelectQuery.h>
#include <Parsers/ParserSelectQuery.h>
#include <Parsers/ParserSampleRatio.h>
#include <Parsers/ParserTablesInSelectQuery.h>
2016-07-18 00:14:24 +00:00
namespace DB
{
namespace ErrorCodes
{
extern const int SYNTAX_ERROR;
}
bool ParserTableExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
2016-07-18 00:14:24 +00:00
{
auto res = std::make_shared<ASTTableExpression>();
2022-09-08 15:20:28 +00:00
if (!ParserWithOptionalAlias(std::make_unique<ParserSubquery>(), allow_alias_without_as_keyword).parse(pos, res->subquery, expected)
&& !ParserWithOptionalAlias(std::make_unique<ParserFunction>(false, true), allow_alias_without_as_keyword).parse(pos, res->table_function, expected)
2022-09-08 15:20:28 +00:00
&& !ParserWithOptionalAlias(std::make_unique<ParserCompoundIdentifier>(true, true), allow_alias_without_as_keyword)
.parse(pos, res->database_and_table_name, expected)
&& !ParserWithOptionalAlias(std::make_unique<ParserTableAsStringLiteralIdentifier>(), allow_alias_without_as_keyword)
.parse(pos, res->database_and_table_name, expected))
2016-07-18 00:14:24 +00:00
return false;
2016-07-18 00:14:24 +00:00
/// FINAL
if (ParserKeyword("FINAL").ignore(pos, expected))
2016-07-18 00:14:24 +00:00
res->final = true;
2016-07-18 00:14:24 +00:00
/// SAMPLE number
if (ParserKeyword("SAMPLE").ignore(pos, expected))
2016-07-18 00:14:24 +00:00
{
ParserSampleRatio ratio;
if (!ratio.parse(pos, res->sample_size, expected))
2016-07-18 00:14:24 +00:00
return false;
2016-07-18 00:14:24 +00:00
/// OFFSET number
if (ParserKeyword("OFFSET").ignore(pos, expected))
2016-07-18 00:14:24 +00:00
{
if (!ratio.parse(pos, res->sample_offset, expected))
2016-07-18 00:14:24 +00:00
return false;
}
}
2016-07-18 00:14:24 +00:00
if (res->database_and_table_name)
res->children.emplace_back(res->database_and_table_name);
if (res->table_function)
res->children.emplace_back(res->table_function);
if (res->subquery)
res->children.emplace_back(res->subquery);
if (res->sample_size)
res->children.emplace_back(res->sample_size);
if (res->sample_offset)
res->children.emplace_back(res->sample_offset);
2020-10-26 15:49:00 +00:00
assert(res->database_and_table_name || res->table_function || res->subquery);
2016-07-18 00:14:24 +00:00
node = res;
return true;
}
bool ParserArrayJoin::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
2016-07-18 00:14:24 +00:00
{
auto res = std::make_shared<ASTArrayJoin>();
2016-07-18 00:14:24 +00:00
/// [LEFT] ARRAY JOIN expr list
Pos saved_pos = pos;
bool has_array_join = false;
if (ParserKeyword("LEFT ARRAY JOIN").ignore(pos, expected))
2016-07-18 00:14:24 +00:00
{
res->kind = ASTArrayJoin::Kind::Left;
has_array_join = true;
}
else
{
pos = saved_pos;
2016-07-18 00:14:24 +00:00
/// INNER may be specified explicitly, otherwise it is assumed as default.
ParserKeyword("INNER").ignore(pos, expected);
if (ParserKeyword("ARRAY JOIN").ignore(pos, expected))
2016-07-18 00:14:24 +00:00
{
res->kind = ASTArrayJoin::Kind::Inner;
has_array_join = true;
}
}
2016-07-18 00:14:24 +00:00
if (!has_array_join)
return false;
if (!ParserExpressionList(false).parse(pos, res->expression_list, expected))
2016-07-18 00:14:24 +00:00
return false;
2016-07-18 00:14:24 +00:00
if (res->expression_list)
res->children.emplace_back(res->expression_list);
2016-07-18 00:14:24 +00:00
node = res;
return true;
}
void ParserTablesInSelectQueryElement::parseJoinStrictness(Pos & pos, ASTTableJoin & table_join)
{
if (ParserKeyword("ANY").ignore(pos))
2022-07-29 16:30:50 +00:00
table_join.strictness = JoinStrictness::Any;
else if (ParserKeyword("ALL").ignore(pos))
2022-07-29 16:30:50 +00:00
table_join.strictness = JoinStrictness::All;
else if (ParserKeyword("ASOF").ignore(pos))
2022-07-29 16:30:50 +00:00
table_join.strictness = JoinStrictness::Asof;
else if (ParserKeyword("SEMI").ignore(pos))
2022-07-29 16:30:50 +00:00
table_join.strictness = JoinStrictness::Semi;
else if (ParserKeyword("ANTI").ignore(pos) || ParserKeyword("ONLY").ignore(pos))
2022-07-29 16:30:50 +00:00
table_join.strictness = JoinStrictness::Anti;
}
bool ParserTablesInSelectQueryElement::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
2016-07-18 00:14:24 +00:00
{
auto res = std::make_shared<ASTTablesInSelectQueryElement>();
if (is_first)
2016-07-18 00:14:24 +00:00
{
2022-09-08 15:20:28 +00:00
if (!ParserTableExpression(allow_alias_without_as_keyword).parse(pos, res->table_expression, expected))
2016-07-18 00:14:24 +00:00
return false;
}
else if (ParserArrayJoin().parse(pos, res->array_join, expected))
{
}
2016-07-18 00:14:24 +00:00
else
{
auto table_join = std::make_shared<ASTTableJoin>();
if (pos->type == TokenType::Comma)
2016-07-18 00:14:24 +00:00
{
++pos;
2022-07-29 16:30:50 +00:00
table_join->kind = JoinKind::Comma;
2016-07-18 00:14:24 +00:00
}
else
{
if (ParserKeyword("GLOBAL").ignore(pos))
2022-07-29 16:30:50 +00:00
table_join->locality = JoinLocality::Global;
else if (ParserKeyword("LOCAL").ignore(pos))
2022-07-29 16:30:50 +00:00
table_join->locality = JoinLocality::Local;
2022-07-29 16:30:50 +00:00
table_join->strictness = JoinStrictness::Unspecified;
/// Legacy: allow JOIN type before JOIN kind
parseJoinStrictness(pos, *table_join);
bool no_kind = false;
if (ParserKeyword("INNER").ignore(pos))
2022-07-29 16:30:50 +00:00
table_join->kind = JoinKind::Inner;
else if (ParserKeyword("LEFT").ignore(pos))
2022-07-29 16:30:50 +00:00
table_join->kind = JoinKind::Left;
else if (ParserKeyword("RIGHT").ignore(pos))
2022-07-29 16:30:50 +00:00
table_join->kind = JoinKind::Right;
else if (ParserKeyword("FULL").ignore(pos))
2022-07-29 16:30:50 +00:00
table_join->kind = JoinKind::Full;
else if (ParserKeyword("CROSS").ignore(pos))
2022-07-29 16:30:50 +00:00
table_join->kind = JoinKind::Cross;
2016-07-18 00:14:24 +00:00
else
no_kind = true;
/// Standard position: JOIN type after JOIN kind
parseJoinStrictness(pos, *table_join);
/// Optional OUTER keyword for outer joins.
2022-07-29 16:30:50 +00:00
if (table_join->kind == JoinKind::Left
|| table_join->kind == JoinKind::Right
|| table_join->kind == JoinKind::Full)
{
ParserKeyword("OUTER").ignore(pos);
}
if (no_kind)
2016-07-18 00:14:24 +00:00
{
2018-09-17 13:33:19 +00:00
/// Use INNER by default as in another DBMS.
2022-07-29 16:30:50 +00:00
if (table_join->strictness == JoinStrictness::Semi ||
table_join->strictness == JoinStrictness::Anti)
table_join->kind = JoinKind::Left;
2019-12-02 18:07:27 +00:00
else
2022-07-29 16:30:50 +00:00
table_join->kind = JoinKind::Inner;
2016-07-18 00:14:24 +00:00
}
2022-07-29 16:30:50 +00:00
if (table_join->strictness != JoinStrictness::Unspecified
&& table_join->kind == JoinKind::Cross)
throw Exception(ErrorCodes::SYNTAX_ERROR, "You must not specify ANY or ALL for CROSS JOIN.");
2022-07-29 16:30:50 +00:00
if ((table_join->strictness == JoinStrictness::Semi || table_join->strictness == JoinStrictness::Anti) &&
(table_join->kind != JoinKind::Left && table_join->kind != JoinKind::Right))
throw Exception(ErrorCodes::SYNTAX_ERROR, "SEMI|ANTI JOIN should be LEFT or RIGHT.");
2019-12-02 18:07:27 +00:00
if (!ParserKeyword("JOIN").ignore(pos, expected))
2016-07-18 00:14:24 +00:00
return false;
}
2022-09-08 15:20:28 +00:00
if (!ParserTableExpression(allow_alias_without_as_keyword).parse(pos, res->table_expression, expected))
2016-07-18 00:14:24 +00:00
return false;
2022-07-29 16:30:50 +00:00
if (table_join->kind != JoinKind::Comma
&& table_join->kind != JoinKind::Cross)
2016-07-18 00:14:24 +00:00
{
if (ParserKeyword("USING").ignore(pos, expected))
2016-07-18 00:14:24 +00:00
{
/// Expression for USING could be in parentheses or not.
bool in_parens = pos->type == TokenType::OpeningRoundBracket;
2016-07-18 00:14:24 +00:00
if (in_parens)
++pos;
if (!ParserExpressionList(false).parse(pos, table_join->using_expression_list, expected))
2016-07-18 00:14:24 +00:00
return false;
2016-07-18 00:14:24 +00:00
if (in_parens)
{
if (pos->type != TokenType::ClosingRoundBracket)
2016-07-18 00:14:24 +00:00
return false;
++pos;
2016-07-18 00:14:24 +00:00
}
}
else if (ParserKeyword("ON").ignore(pos, expected))
2016-07-18 00:14:24 +00:00
{
2022-09-07 21:41:37 +00:00
if (!ParserExpression().parse(pos, table_join->on_expression, expected))
2016-07-18 00:14:24 +00:00
return false;
}
else
{
return false;
}
}
2016-07-18 00:14:24 +00:00
if (table_join->using_expression_list)
table_join->children.emplace_back(table_join->using_expression_list);
if (table_join->on_expression)
table_join->children.emplace_back(table_join->on_expression);
2016-07-18 00:14:24 +00:00
res->table_join = table_join;
}
2016-07-18 00:14:24 +00:00
if (res->table_expression)
res->children.emplace_back(res->table_expression);
if (res->table_join)
res->children.emplace_back(res->table_join);
if (res->array_join)
res->children.emplace_back(res->array_join);
2016-07-18 00:14:24 +00:00
node = res;
return true;
}
bool ParserTablesInSelectQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
2016-07-18 00:14:24 +00:00
{
auto res = std::make_shared<ASTTablesInSelectQuery>();
ASTPtr child;
2022-09-08 15:20:28 +00:00
if (ParserTablesInSelectQueryElement(true, allow_alias_without_as_keyword).parse(pos, child, expected))
2016-07-18 00:14:24 +00:00
res->children.emplace_back(child);
else
return false;
2022-09-08 15:20:28 +00:00
while (ParserTablesInSelectQueryElement(false, allow_alias_without_as_keyword).parse(pos, child, expected))
2016-07-18 00:14:24 +00:00
res->children.emplace_back(child);
2016-07-18 01:20:53 +00:00
node = res;
2016-07-18 00:14:24 +00:00
return true;
}
}