From d4fe0fae8fb3b0b7688f6516b5a0189ad9f14c40 Mon Sep 17 00:00:00 2001 From: Nikolay Degterinsky Date: Thu, 8 Sep 2022 00:30:44 +0000 Subject: [PATCH 1/3] Add 'FROM table SELECT column' syntax --- src/Parsers/ParserSelectQuery.cpp | 9 ++++++++- .../0_stateless/02417_from_select_syntax.reference | 2 ++ tests/queries/0_stateless/02417_from_select_syntax.sql | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 tests/queries/0_stateless/02417_from_select_syntax.reference create mode 100644 tests/queries/0_stateless/02417_from_select_syntax.sql diff --git a/src/Parsers/ParserSelectQuery.cpp b/src/Parsers/ParserSelectQuery.cpp index 66428b144bf5..936d7758f46a 100644 --- a/src/Parsers/ParserSelectQuery.cpp +++ b/src/Parsers/ParserSelectQuery.cpp @@ -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().parse(pos, tables, expected)) + return false; + } + /// SELECT [ALL/DISTINCT [ON (expr_list)]] [TOP N [WITH TIES]] expr_list { bool has_all = false; @@ -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; diff --git a/tests/queries/0_stateless/02417_from_select_syntax.reference b/tests/queries/0_stateless/02417_from_select_syntax.reference new file mode 100644 index 000000000000..aa47d0d46d47 --- /dev/null +++ b/tests/queries/0_stateless/02417_from_select_syntax.reference @@ -0,0 +1,2 @@ +0 +0 diff --git a/tests/queries/0_stateless/02417_from_select_syntax.sql b/tests/queries/0_stateless/02417_from_select_syntax.sql new file mode 100644 index 000000000000..ab3efa4292ea --- /dev/null +++ b/tests/queries/0_stateless/02417_from_select_syntax.sql @@ -0,0 +1,2 @@ +FROM numbers(1) SELECT number; +WITH 1 as n FROM numbers(1) SELECT number * n; From fc6ec8474ec31e8443da1dad45ecc748ea844624 Mon Sep 17 00:00:00 2001 From: Nikolay Degterinsky Date: Thu, 8 Sep 2022 15:20:28 +0000 Subject: [PATCH 2/3] Better --- src/Parsers/ParserSelectQuery.cpp | 2 +- src/Parsers/ParserTablesInSelectQuery.cpp | 14 +++++++------- src/Parsers/ParserTablesInSelectQuery.h | 18 +++++++++++++++++- .../02417_from_select_syntax.reference | 2 ++ .../0_stateless/02417_from_select_syntax.sql | 2 ++ 5 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/Parsers/ParserSelectQuery.cpp b/src/Parsers/ParserSelectQuery.cpp index 936d7758f46a..049c4ab4b448 100644 --- a/src/Parsers/ParserSelectQuery.cpp +++ b/src/Parsers/ParserSelectQuery.cpp @@ -111,7 +111,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 (!ParserTablesInSelectQuery().parse(pos, tables, expected)) + if (!ParserTablesInSelectQuery(false).parse(pos, tables, expected)) return false; } diff --git a/src/Parsers/ParserTablesInSelectQuery.cpp b/src/Parsers/ParserTablesInSelectQuery.cpp index 8137093b9905..67da9d77beec 100644 --- a/src/Parsers/ParserTablesInSelectQuery.cpp +++ b/src/Parsers/ParserTablesInSelectQuery.cpp @@ -21,9 +21,9 @@ bool ParserTableExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expec { auto res = std::make_shared(); - if (!ParserWithOptionalAlias(std::make_unique(), true).parse(pos, res->subquery, expected) - && !ParserWithOptionalAlias(std::make_unique(true, true), true).parse(pos, res->table_function, expected) - && !ParserWithOptionalAlias(std::make_unique(true, true), true) + if (!ParserWithOptionalAlias(std::make_unique(), allow_alias_without_as_keyword).parse(pos, res->subquery, expected) + && !ParserWithOptionalAlias(std::make_unique(true, true), allow_alias_without_as_keyword).parse(pos, res->table_function, expected) + && !ParserWithOptionalAlias(std::make_unique(true, true), allow_alias_without_as_keyword) .parse(pos, res->database_and_table_name, expected)) return false; @@ -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)) @@ -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 @@ -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; diff --git a/src/Parsers/ParserTablesInSelectQuery.h b/src/Parsers/ParserTablesInSelectQuery.h index 772f1992f4d0..633860920b4a 100644 --- a/src/Parsers/ParserTablesInSelectQuery.h +++ b/src/Parsers/ParserTablesInSelectQuery.h @@ -12,16 +12,24 @@ struct ASTTableJoin; */ class ParserTablesInSelectQuery : public IParserBase { +public: + 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"; } @@ -29,6 +37,7 @@ class ParserTablesInSelectQueryElement : public IParserBase private: bool is_first; + bool allow_alias_without_as_keyword; static void parseJoinStrictness(Pos & pos, ASTTableJoin & table_join); }; @@ -36,9 +45,16 @@ class ParserTablesInSelectQueryElement : public IParserBase 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; }; diff --git a/tests/queries/0_stateless/02417_from_select_syntax.reference b/tests/queries/0_stateless/02417_from_select_syntax.reference index aa47d0d46d47..44e0be8e3569 100644 --- a/tests/queries/0_stateless/02417_from_select_syntax.reference +++ b/tests/queries/0_stateless/02417_from_select_syntax.reference @@ -1,2 +1,4 @@ 0 0 +0 +0 diff --git a/tests/queries/0_stateless/02417_from_select_syntax.sql b/tests/queries/0_stateless/02417_from_select_syntax.sql index ab3efa4292ea..ce6cb3a14da1 100644 --- a/tests/queries/0_stateless/02417_from_select_syntax.sql +++ b/tests/queries/0_stateless/02417_from_select_syntax.sql @@ -1,2 +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; From 2ce0f1b678b90f7015b1f59962b04bc16abfb301 Mon Sep 17 00:00:00 2001 From: Nikolay Degterinsky <43110995+evillique@users.noreply.github.com> Date: Sat, 17 Sep 2022 01:08:36 +0200 Subject: [PATCH 3/3] Update src/Parsers/ParserTablesInSelectQuery.h Co-authored-by: Sergei Trifonov --- src/Parsers/ParserTablesInSelectQuery.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Parsers/ParserTablesInSelectQuery.h b/src/Parsers/ParserTablesInSelectQuery.h index 633860920b4a..428b14826633 100644 --- a/src/Parsers/ParserTablesInSelectQuery.h +++ b/src/Parsers/ParserTablesInSelectQuery.h @@ -13,7 +13,7 @@ struct ASTTableJoin; class ParserTablesInSelectQuery : public IParserBase { public: - ParserTablesInSelectQuery(bool allow_alias_without_as_keyword_ = true) + explicit ParserTablesInSelectQuery(bool allow_alias_without_as_keyword_ = true) : allow_alias_without_as_keyword(allow_alias_without_as_keyword_) {} protected: