diff --git a/dbms/src/Interpreters/JoinToSubqueryTransformVisitor.cpp b/dbms/src/Interpreters/JoinToSubqueryTransformVisitor.cpp index 22deeabfcc1..43680d7aa61 100644 --- a/dbms/src/Interpreters/JoinToSubqueryTransformVisitor.cpp +++ b/dbms/src/Interpreters/JoinToSubqueryTransformVisitor.cpp @@ -33,30 +33,46 @@ namespace { /// Replace asterisks in select_expression_list with column identifiers -struct ExtractAsterisksMatcher +class ExtractAsterisksMatcher { +public: using Visitor = InDepthNodeVisitor; struct Data { std::unordered_map table_columns; + std::vector tables_order; std::shared_ptr new_select_expression_list; Data(const Context & context, const std::vector & table_expressions) { + tables_order.reserve(table_expressions.size()); for (const auto & expr : table_expressions) { if (expr->subquery) { table_columns.clear(); + tables_order.clear(); break; } String table_name = DatabaseAndTableWithAlias(*expr, context.getCurrentDatabase()).getQualifiedNamePrefix(false); NamesAndTypesList columns = getNamesAndTypeListFromTableExpression(*expr, context); + tables_order.push_back(table_name); table_columns.emplace(std::move(table_name), std::move(columns)); } } + + void addTableColumns(const String & table_name) + { + auto it = table_columns.find(table_name); + if (it == table_columns.end()) + throw Exception("Unknown qualified identifier: " + table_name, ErrorCodes::UNKNOWN_IDENTIFIER); + + for (const auto & column : it->second) + new_select_expression_list->children.push_back( + std::make_shared(std::vector{it->first, column.name})); + } }; static bool needChildVisit(ASTPtr &, const ASTPtr &) { return false; } @@ -69,6 +85,7 @@ struct ExtractAsterisksMatcher visit(*t, ast, data); } +private: static void visit(ASTSelectQuery & node, ASTPtr &, Data & data) { if (data.table_columns.empty()) @@ -101,10 +118,8 @@ struct ExtractAsterisksMatcher { has_asterisks = true; - for (auto & pr : data.table_columns) - for (const auto & column : pr.second) - data.new_select_expression_list->children.push_back( - std::make_shared(std::vector{pr.first, column.name})); + for (auto & table_name : data.tables_order) + data.addTableColumns(table_name); } else if (child->as()) { @@ -114,13 +129,7 @@ struct ExtractAsterisksMatcher throw Exception("Logical error: qualified asterisk must have exactly one child", ErrorCodes::LOGICAL_ERROR); ASTIdentifier & identifier = child->children[0]->as(); - auto it = data.table_columns.find(identifier.name); - if (it == data.table_columns.end()) - throw Exception("Unknown qualified identifier: " + identifier.name, ErrorCodes::UNKNOWN_IDENTIFIER); - - for (const auto & column : it->second) - data.new_select_expression_list->children.push_back( - std::make_shared(std::vector{it->first, column.name})); + data.addTableColumns(identifier.name); } else data.new_select_expression_list->children.push_back(child); diff --git a/dbms/tests/queries/0_stateless/00820_multiple_joins.reference b/dbms/tests/queries/0_stateless/00820_multiple_joins.reference index 335c17933ec..6d317230813 100644 --- a/dbms/tests/queries/0_stateless/00820_multiple_joins.reference +++ b/dbms/tests/queries/0_stateless/00820_multiple_joins.reference @@ -32,14 +32,18 @@ 6 6 60 60 12 12 120 120 18 18 180 180 -0 0 0 0 0 -6 6 60 60 600 -12 12 120 120 1200 -18 18 180 180 1800 -0 0 0 0 0 -60 600 6 60 6 -120 1200 12 120 12 -180 1800 18 180 18 +┌─t1.a─┬─t2.a─┬─t2.b─┬─t3.b─┬─t3.c─┐ +│ 0 │ 0 │ 0 │ 0 │ 0 │ +│ 6 │ 6 │ 60 │ 60 │ 600 │ +│ 12 │ 12 │ 120 │ 120 │ 1200 │ +│ 18 │ 18 │ 180 │ 180 │ 1800 │ +└──────┴──────┴──────┴──────┴──────┘ +┌─t1.a─┬─t2.a─┬─t2.b─┬─t3.b─┬─t3.c─┐ +│ 0 │ 0 │ 0 │ 0 │ 0 │ +│ 6 │ 6 │ 60 │ 60 │ 600 │ +│ 12 │ 12 │ 120 │ 120 │ 1200 │ +│ 18 │ 18 │ 180 │ 180 │ 1800 │ +└──────┴──────┴──────┴──────┴──────┘ 0 0 0 0 0 0 0 6 6 60 60 66 66 120 12 12 120 120 132 132 240 diff --git a/dbms/tests/queries/0_stateless/00820_multiple_joins.sql b/dbms/tests/queries/0_stateless/00820_multiple_joins.sql index 628a3d9fd8c..8588edc5641 100644 --- a/dbms/tests/queries/0_stateless/00820_multiple_joins.sql +++ b/dbms/tests/queries/0_stateless/00820_multiple_joins.sql @@ -60,12 +60,14 @@ join table3 as t3 on table2.b = table3.b; select t1.*, t2.*, t3.* from table1 as t1 join table2 as t2 on table1.a = table2.a -join table3 as t3 on table2.b = table3.b; +join table3 as t3 on table2.b = table3.b +FORMAT PrettyCompactNoEscapes; select * from table1 as t1 join table2 as t2 on t1.a = t2.a -join table3 as t3 on t2.b = t3.b; +join table3 as t3 on t2.b = t3.b +FORMAT PrettyCompactNoEscapes; select t1.a as t1_a, t2.a as t2_a, t2.b as t2_b, t3.b as t3_b, (t1.a + table2.b) as t1_t2_x, (table1.a + table3.b) as t1_t3_x, (t2.b + t3.b) as t2_t3_x