diff --git a/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp b/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp index 474f1454155..7d4d38f5082 100644 --- a/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp +++ b/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp @@ -395,7 +395,7 @@ ASTs PredicateExpressionsOptimizer::evaluateAsterisk(ASTSelectQuery * select_que { const auto database_and_table_ast = static_cast(table_expression->database_and_table_name.get()); const auto database_and_table_name = getDatabaseAndTableNameFromIdentifier(*database_and_table_ast); - storage = context.tryGetTable(database_and_table_name.first, database_and_table_name.second); + storage = context.getTable(database_and_table_name.first, database_and_table_name.second); } const auto block = storage->getSampleBlock(); diff --git a/dbms/src/Parsers/ASTSelectQuery.cpp b/dbms/src/Parsers/ASTSelectQuery.cpp index 5f7ea7dc91a..0cf19a28851 100644 --- a/dbms/src/Parsers/ASTSelectQuery.cpp +++ b/dbms/src/Parsers/ASTSelectQuery.cpp @@ -7,6 +7,7 @@ #include #include #include +#include "ASTSelectWithUnionQuery.h" namespace DB @@ -339,25 +340,41 @@ const ASTTablesInSelectQueryElement * ASTSelectQuery::join() const void ASTSelectQuery::setDatabaseIfNeeded(const String & database_name) { - ASTTableExpression * table_expression = getFirstTableExpression(*this); - if (!table_expression) + if (!tables) return; - if (!table_expression->database_and_table_name) - return; + ASTTablesInSelectQuery & tables_in_select_query = static_cast(*tables); - if (table_expression->database_and_table_name->children.empty()) + for (auto & child : tables_in_select_query.children) { - ASTPtr database = ASTIdentifier::createSpecial(database_name); - ASTPtr table = table_expression->database_and_table_name; + const auto & tables_element = static_cast(*child); + if (tables_element.table_expression) + { + const auto table_expression = static_cast(tables_element.table_expression.get()); - const String & old_name = static_cast(*table_expression->database_and_table_name).name; - table_expression->database_and_table_name = ASTIdentifier::createSpecial(database_name + "." + old_name); - table_expression->database_and_table_name->children = {database, table}; - } - else if (table_expression->database_and_table_name->children.size() != 2) - { - throw Exception("Logical error: more than two components in table expression", ErrorCodes::LOGICAL_ERROR); + if (!table_expression->database_and_table_name && !table_expression->subquery) + continue; + + if (table_expression->subquery) + { + const auto subquery = static_cast(table_expression->subquery.get()); + const auto select_with_union_query = static_cast(subquery->children[0].get()); + select_with_union_query->setDatabaseIfNeeded(database_name); + } + else if (table_expression->database_and_table_name->children.empty()) + { + ASTPtr database = ASTIdentifier::createSpecial(database_name); + ASTPtr table = table_expression->database_and_table_name; + + const String & old_name = static_cast(*table_expression->database_and_table_name).name; + table_expression->database_and_table_name = ASTIdentifier::createSpecial(database_name + "." + old_name); + table_expression->database_and_table_name->children = {database, table}; + } + else if (table_expression->database_and_table_name->children.size() != 2) + { + throw Exception("Logical error: more than two components in table expression", ErrorCodes::LOGICAL_ERROR); + } + } } } diff --git a/dbms/tests/queries/0_stateless/00740_database_in_nested_view.reference b/dbms/tests/queries/0_stateless/00740_database_in_nested_view.reference new file mode 100644 index 00000000000..c9854e61c3d --- /dev/null +++ b/dbms/tests/queries/0_stateless/00740_database_in_nested_view.reference @@ -0,0 +1,6 @@ +1 +1 +1 1 +1 +1 +1 1 diff --git a/dbms/tests/queries/0_stateless/00740_database_in_nested_view.sql b/dbms/tests/queries/0_stateless/00740_database_in_nested_view.sql new file mode 100644 index 00000000000..e4dabc3a5a6 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00740_database_in_nested_view.sql @@ -0,0 +1,23 @@ +DROP TABLE IF EXISTS test.test; +DROP TABLE IF EXISTS test.test_view; +DROP TABLE IF EXISTS test.test_nested_view; +DROP TABLE IF EXISTS test.test_joined_view; + +USE test; +CREATE VIEW test AS SELECT 1 AS N; +CREATE VIEW test_view AS SELECT * FROM test; +CREATE VIEW test_nested_view AS SELECT * FROM (SELECT * FROM test); +CREATE VIEW test_joined_view AS SELECT * FROM test ANY LEFT JOIN test USING N; + +SELECT * FROM test_view; +SELECT * FROM test_nested_view; +SELECT * FROM test_joined_view; + +USE default; +SELECT * FROM test.test_view; +SELECT * FROM test.test_nested_view; +SELECT * FROM test.test_joined_view; + +DROP TABLE IF EXISTS test.test; +DROP TABLE IF EXISTS test.test_view; +DROP TABLE IF EXISTS test.test_nested_view; diff --git a/dbms/tests/queries/bugs/database_in_view.sql b/dbms/tests/queries/bugs/database_in_view.sql deleted file mode 100644 index 0b7149e4e88..00000000000 --- a/dbms/tests/queries/bugs/database_in_view.sql +++ /dev/null @@ -1,18 +0,0 @@ -DROP TABLE IF EXISTS test.whoami; -DROP TABLE IF EXISTS test.tellme; -DROP TABLE IF EXISTS test.tellme_nested; - -use test; -create view whoami as select 1 as n; -create view tellme as select * from whoami; -create view tellme_nested as select * from (select * from whoami); -select * from tellme; -select * from tellme_nested; - -use default; -select * from test.tellme; -select * from test.tellme_nested; - -DROP TABLE test.whoami; -DROP TABLE test.tellme; -DROP TABLE test.tellme_nested;