Skip to content

Commit

Permalink
Merge pull request ClickHouse#41095 from evillique/from-select
Browse files Browse the repository at this point in the history
Add 'FROM table SELECT column' syntax
  • Loading branch information
evillique authored Dec 2, 2022
2 parents 9eeed56 + af9ab4c commit c2ceb78
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 9 deletions.
9 changes: 8 additions & 1 deletion src/Parsers/ParserSelectQuery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ bool ParserSelectQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
}
}

/// FROM database.table or FROM table or FROM (subquery) or FROM tableFunction(...)
if (s_from.ignore(pos, expected))
{
if (!ParserTablesInSelectQuery(false).parse(pos, tables, expected))
return false;
}

/// SELECT [ALL/DISTINCT [ON (expr_list)]] [TOP N [WITH TIES]] expr_list
{
bool has_all = false;
Expand Down Expand Up @@ -166,7 +173,7 @@ bool ParserSelectQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
}

/// FROM database.table or FROM table or FROM (subquery) or FROM tableFunction(...)
if (s_from.ignore(pos, expected))
if (!tables && s_from.ignore(pos, expected))
{
if (!ParserTablesInSelectQuery().parse(pos, tables, expected))
return false;
Expand Down
14 changes: 7 additions & 7 deletions src/Parsers/ParserTablesInSelectQuery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ bool ParserTableExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
{
auto res = std::make_shared<ASTTableExpression>();

if (!ParserWithOptionalAlias(std::make_unique<ParserSubquery>(), true).parse(pos, res->subquery, expected)
&& !ParserWithOptionalAlias(std::make_unique<ParserFunction>(false, true), true).parse(pos, res->table_function, expected)
&& !ParserWithOptionalAlias(std::make_unique<ParserCompoundIdentifier>(true, true), true)
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)
&& !ParserWithOptionalAlias(std::make_unique<ParserCompoundIdentifier>(true, true), allow_alias_without_as_keyword)
.parse(pos, res->database_and_table_name, expected))
return false;

Expand Down Expand Up @@ -126,7 +126,7 @@ bool ParserTablesInSelectQueryElement::parseImpl(Pos & pos, ASTPtr & node, Expec

if (is_first)
{
if (!ParserTableExpression().parse(pos, res->table_expression, expected))
if (!ParserTableExpression(allow_alias_without_as_keyword).parse(pos, res->table_expression, expected))
return false;
}
else if (ParserArrayJoin().parse(pos, res->array_join, expected))
Expand Down Expand Up @@ -200,7 +200,7 @@ bool ParserTablesInSelectQueryElement::parseImpl(Pos & pos, ASTPtr & node, Expec
return false;
}

if (!ParserTableExpression().parse(pos, res->table_expression, expected))
if (!ParserTableExpression(allow_alias_without_as_keyword).parse(pos, res->table_expression, expected))
return false;

if (table_join->kind != JoinKind::Comma
Expand Down Expand Up @@ -261,12 +261,12 @@ bool ParserTablesInSelectQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & e

ASTPtr child;

if (ParserTablesInSelectQueryElement(true).parse(pos, child, expected))
if (ParserTablesInSelectQueryElement(true, allow_alias_without_as_keyword).parse(pos, child, expected))
res->children.emplace_back(child);
else
return false;

while (ParserTablesInSelectQueryElement(false).parse(pos, child, expected))
while (ParserTablesInSelectQueryElement(false, allow_alias_without_as_keyword).parse(pos, child, expected))
res->children.emplace_back(child);

node = res;
Expand Down
18 changes: 17 additions & 1 deletion src/Parsers/ParserTablesInSelectQuery.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,49 @@ struct ASTTableJoin;
*/
class ParserTablesInSelectQuery : public IParserBase
{
public:
explicit ParserTablesInSelectQuery(bool allow_alias_without_as_keyword_ = true)
: allow_alias_without_as_keyword(allow_alias_without_as_keyword_) {}

protected:
const char * getName() const override { return "table, table function, subquery or list of joined tables"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;

private:
bool allow_alias_without_as_keyword;
};


class ParserTablesInSelectQueryElement : public IParserBase
{
public:
explicit ParserTablesInSelectQueryElement(bool is_first_) : is_first(is_first_) {}
explicit ParserTablesInSelectQueryElement(bool is_first_, bool allow_alias_without_as_keyword_ = true)
: is_first(is_first_), allow_alias_without_as_keyword(allow_alias_without_as_keyword_) {}

protected:
const char * getName() const override { return "table, table function, subquery or list of joined tables"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;

private:
bool is_first;
bool allow_alias_without_as_keyword;

static void parseJoinStrictness(Pos & pos, ASTTableJoin & table_join);
};


class ParserTableExpression : public IParserBase
{
public:
explicit ParserTableExpression(bool allow_alias_without_as_keyword_ = true)
: allow_alias_without_as_keyword(allow_alias_without_as_keyword_) {}

protected:
const char * getName() const override { return "table or subquery or table function"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;

private:
bool allow_alias_without_as_keyword;
};


Expand Down
4 changes: 4 additions & 0 deletions tests/queries/0_stateless/02417_from_select_syntax.reference
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
0
0
0
0
4 changes: 4 additions & 0 deletions tests/queries/0_stateless/02417_from_select_syntax.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM numbers(1) SELECT number;
WITH 1 as n FROM numbers(1) SELECT number * n;
FROM (FROM numbers(1) SELECT *) SELECT number;
FROM (FROM numbers(1) SELECT *) AS select SELECT number;

0 comments on commit c2ceb78

Please sign in to comment.