diff --git a/dbms/src/Interpreters/GlobalSubqueriesVisitor.h b/dbms/src/Interpreters/GlobalSubqueriesVisitor.h index c99f8d95e49..4b94a804858 100644 --- a/dbms/src/Interpreters/GlobalSubqueriesVisitor.h +++ b/dbms/src/Interpreters/GlobalSubqueriesVisitor.h @@ -46,48 +46,36 @@ public: has_global_subqueries(has_global_subqueries_) {} - void addExternalStorage(ASTPtr & subquery_or_table_name_or_table_expression) + void addExternalStorage(ASTPtr & ast, bool set_alias = false) { /// With nondistributed queries, creating temporary tables does not make sense. if (!is_remote) return; - ASTPtr subquery; - ASTPtr table_name; - ASTPtr subquery_or_table_name; + bool is_table = false; + ASTPtr subquery_or_table_name = ast; /// ASTIdentifier | ASTSubquery | ASTTableExpression - if (subquery_or_table_name_or_table_expression->as()) - { - table_name = subquery_or_table_name_or_table_expression; - subquery_or_table_name = table_name; - } - else if (const auto * ast_table_expr = subquery_or_table_name_or_table_expression->as()) + if (const auto * ast_table_expr = ast->as()) { + subquery_or_table_name = ast_table_expr->subquery; + if (ast_table_expr->database_and_table_name) { - table_name = ast_table_expr->database_and_table_name; - subquery_or_table_name = table_name; - } - else if (ast_table_expr->subquery) - { - subquery = ast_table_expr->subquery; - subquery_or_table_name = subquery; + subquery_or_table_name = ast_table_expr->database_and_table_name; + is_table = true; } } - else if (subquery_or_table_name_or_table_expression->as()) - { - subquery = subquery_or_table_name_or_table_expression; - subquery_or_table_name = subquery; - } + else if (ast->as()) + is_table = true; if (!subquery_or_table_name) throw Exception("Logical error: unknown AST element passed to ExpressionAnalyzer::addExternalStorage method", ErrorCodes::LOGICAL_ERROR); - if (table_name) + if (is_table) { /// If this is already an external table, you do not need to add anything. Just remember its presence. - if (external_tables.end() != external_tables.find(*getIdentifierName(table_name))) + if (external_tables.end() != external_tables.find(*getIdentifierName(subquery_or_table_name))) return; } @@ -114,8 +102,16 @@ public: */ auto database_and_table_name = createTableIdentifier("", external_table_name); + if (set_alias) + { + String alias = subquery_or_table_name->tryGetAlias(); + if (auto * table_name = subquery_or_table_name->as()) + if (alias.empty()) + alias = table_name->shortName(); + database_and_table_name->setAlias(alias); + } - if (auto * ast_table_expr = subquery_or_table_name_or_table_expression->as()) + if (auto * ast_table_expr = ast->as()) { ast_table_expr->subquery.reset(); ast_table_expr->database_and_table_name = database_and_table_name; @@ -124,7 +120,7 @@ public: ast_table_expr->children.emplace_back(database_and_table_name); } else - subquery_or_table_name_or_table_expression = database_and_table_name; + ast = database_and_table_name; external_tables[external_table_name] = external_storage; subqueries_for_sets[external_table_name].source = interpreter->execute().in; @@ -170,7 +166,7 @@ private: { if (table_elem.table_join && table_elem.table_join->as().locality == ASTTableJoin::Locality::Global) { - data.addExternalStorage(table_elem.table_expression); + data.addExternalStorage(table_elem.table_expression, true); data.has_global_subqueries = true; } } diff --git a/dbms/tests/queries/0_stateless/00857_global_joinsavel_table_alias.reference b/dbms/tests/queries/0_stateless/00857_global_joinsavel_table_alias.reference new file mode 100644 index 00000000000..3ccf7f67249 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00857_global_joinsavel_table_alias.reference @@ -0,0 +1,12 @@ +One Hundred +Two Hundred +One Hundred +Two Hundred +One Hundred +Two Hundred +One Hundred +Two Hundred +One Hundred +Two Hundred +One Hundred +Two Hundred diff --git a/dbms/tests/queries/0_stateless/00857_global_joinsavel_table_alias.sql b/dbms/tests/queries/0_stateless/00857_global_joinsavel_table_alias.sql new file mode 100644 index 00000000000..9286abaf6f7 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00857_global_joinsavel_table_alias.sql @@ -0,0 +1,59 @@ +USE test; + +DROP TABLE IF EXISTS local_table; +DROP TABLE IF EXISTS other_table; + +CREATE TABLE local_table +( + id Int32, + name String, + ts DateTime, + oth_id Int32 +) ENGINE = MergeTree() PARTITION BY toMonday(ts) ORDER BY (ts, id); + +CREATE TABLE other_table +( + id Int32, + name String, + ts DateTime, + trd_id Int32 +) ENGINE = MergeTree() PARTITION BY toMonday(ts) ORDER BY (ts, id); + +INSERT INTO local_table VALUES(1, 'One', now(), 100); +INSERT INTO local_table VALUES(2, 'Two', now(), 200); +INSERT INTO other_table VALUES(100, 'One Hundred', now(), 1000); +INSERT INTO other_table VALUES(200, 'Two Hundred', now(), 2000); + +-- FIXME: test.other_table -> other_table in first query breaks test (external tables cache error) +select t2.name from remote('127.0.0.2', 'test.local_table') as t1 +left join test.other_table as t2 +on t1.oth_id = t2.id +order by t2.name; + +select t2.name from test.other_table as t2 +global right join remote('127.0.0.2', 'test.local_table') as t1 +on t1.oth_id = t2.id +order by t2.name; + +select t2.name from remote('127.0.0.2', 'test.local_table') as t1 +global left join other_table as t2 +on t1.oth_id = t2.id +order by t2.name; + +select t2.name from remote('127.0.0.2', 'test.local_table') as t1 +global left join other_table as t2 +on t1.oth_id = t2.id +order by t2.name; + +select other_table.name from remote('127.0.0.2', 'test.local_table') as t1 +global left join other_table +on t1.oth_id = other_table.id +order by other_table.name; + +select other_table.name from remote('127.0.0.2', 'test.local_table') as t1 +global left join other_table as t2 +on t1.oth_id = other_table.id +order by other_table.name; + +DROP TABLE local_table; +DROP TABLE other_table;