| 25 | |
| 26 | |
| 27 | bool ParserTableExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) |
| 28 | { |
| 29 | auto res = make_intrusive<ASTTableExpression>(); |
| 30 | |
| 31 | if (!ParserWithOptionalAlias(std::make_unique<ParserSubquery>(), allow_alias_without_as_keyword).parse(pos, res->subquery, expected) |
| 32 | && !ParserWithOptionalAlias(std::make_unique<ParserFunction>(false, true), allow_alias_without_as_keyword).parse(pos, res->table_function, expected) |
| 33 | && !ParserWithOptionalAlias(std::make_unique<ParserCompoundIdentifier>(true, true), allow_alias_without_as_keyword) |
| 34 | .parse(pos, res->database_and_table_name, expected) |
| 35 | && !ParserWithOptionalAlias(std::make_unique<ParserTableAsStringLiteralIdentifier>(), allow_alias_without_as_keyword) |
| 36 | .parse(pos, res->database_and_table_name, expected)) |
| 37 | { |
| 38 | /// Parenthesized table join expression: (t1 JOIN t2 ON ...) → SELECT * FROM t1 JOIN t2 ON ... |
| 39 | /// Standard SQL allows parentheses around joined table expressions in FROM clauses. |
| 40 | if (pos->type == TokenType::OpeningRoundBracket) |
| 41 | { |
| 42 | auto open_paren = pos; |
| 43 | ++pos; |
| 44 | |
| 45 | ASTPtr tables_in_select; |
| 46 | if (ParserTablesInSelectQuery(false).parse(pos, tables_in_select, expected) |
| 47 | && pos->type == TokenType::ClosingRoundBracket |
| 48 | && tables_in_select->as<ASTTablesInSelectQuery &>().children.size() > 1) |
| 49 | { |
| 50 | ++pos; |
| 51 | |
| 52 | /// Build: SELECT * FROM <parsed_tables> |
| 53 | auto select_ast = make_intrusive<ASTSelectQuery>(); |
| 54 | select_ast->setExpression(ASTSelectQuery::Expression::SELECT, make_intrusive<ASTExpressionList>()); |
| 55 | select_ast->select()->children.push_back(make_intrusive<ASTAsterisk>()); |
| 56 | select_ast->setExpression(ASTSelectQuery::Expression::TABLES, std::move(tables_in_select)); |
| 57 | |
| 58 | auto list_of_selects = make_intrusive<ASTExpressionList>(); |
| 59 | list_of_selects->children.push_back(select_ast); |
| 60 | |
| 61 | auto select_with_union = make_intrusive<ASTSelectWithUnionQuery>(); |
| 62 | select_with_union->children.push_back(std::move(list_of_selects)); |
| 63 | select_with_union->list_of_selects = select_with_union->children.back(); |
| 64 | |
| 65 | res->subquery = make_intrusive<ASTSubquery>(std::move(select_with_union)); |
| 66 | |
| 67 | /// Parse optional alias: (t1 CROSS JOIN t2) AS j |
| 68 | ParserAlias alias_parser(allow_alias_without_as_keyword); |
| 69 | ASTPtr alias_node; |
| 70 | if (alias_parser.parse(pos, alias_node, expected)) |
| 71 | res->subquery->setAlias(alias_node->getColumnName()); |
| 72 | } |
| 73 | else |
| 74 | { |
| 75 | pos = open_paren; |
| 76 | return false; |
| 77 | } |
| 78 | } |
| 79 | else |
| 80 | { |
| 81 | return false; |
| 82 | } |
| 83 | } |
| 84 |
nothing calls this directly
no test coverage detected