From 3e60a95cdd2e6c0ff2f2985fd53a8f00585e3bc6 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 6 Jun 2016 21:19:28 +0300 Subject: [PATCH] Allowed subqueries in views [#METR-21586]. --- dbms/include/DB/Storages/StorageView.h | 4 +++ dbms/src/Storages/StorageView.cpp | 46 +++++++++++++++++--------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/dbms/include/DB/Storages/StorageView.h b/dbms/include/DB/Storages/StorageView.h index 97022f4d75..44d79835e0 100644 --- a/dbms/include/DB/Storages/StorageView.h +++ b/dbms/include/DB/Storages/StorageView.h @@ -61,6 +61,10 @@ protected: const NamesAndTypesList & materialized_columns_, const NamesAndTypesList & alias_columns_, const ColumnDefaults & column_defaults_); + +private: + /// Достать из самого внутреннего подзапроса имя базы данных и таблицы: select_database_name, select_table_name. + void extractDependentTable(const ASTSelectQuery & query); }; } diff --git a/dbms/src/Storages/StorageView.cpp b/dbms/src/Storages/StorageView.cpp index 418486537a..6f4061903e 100644 --- a/dbms/src/Storages/StorageView.cpp +++ b/dbms/src/Storages/StorageView.cpp @@ -56,23 +56,38 @@ StorageView::StorageView( inner_query = select; - if (inner_query.database) - select_database_name = typeid_cast(*inner_query.database).name; - else - throw Exception("Logical error while creating StorageView." - " Could not retrieve database name from select query.", - DB::ErrorCodes::LOGICAL_ERROR); + extractDependentTable(inner_query); - if (inner_query.table) - select_table_name = typeid_cast(*inner_query.table).name; + if (!select_table_name.empty()) + context.getGlobalContext().addDependency( + DatabaseAndTableName(select_database_name, select_table_name), + DatabaseAndTableName(database_name, table_name)); +} + + +void StorageView::extractDependentTable(const ASTSelectQuery & query) +{ + if (!query.table) + return; + + if (const ASTIdentifier * ast_id = typeid_cast(query.table.get())) + { + if (!query.database) + throw Exception("Logical error while creating StorageView." + " Could not retrieve database name from select query.", + DB::ErrorCodes::LOGICAL_ERROR); + + select_database_name = typeid_cast(*query.database).name; + select_table_name = ast_id->name; + } + else if (const ASTSelectQuery * ast_select = typeid_cast(query.table.get())) + { + extractDependentTable(*ast_select); + } else throw Exception("Logical error while creating StorageView." " Could not retrieve table name from select query.", DB::ErrorCodes::LOGICAL_ERROR); - - context.getGlobalContext().addDependency( - DatabaseAndTableName(select_database_name, select_table_name), - DatabaseAndTableName(database_name, table_name)); } @@ -110,9 +125,10 @@ BlockInputStreams StorageView::read( void StorageView::drop() { - context.getGlobalContext().removeDependency( - DatabaseAndTableName(select_database_name, select_table_name), - DatabaseAndTableName(database_name, table_name)); + if (!select_table_name.empty()) + context.getGlobalContext().removeDependency( + DatabaseAndTableName(select_database_name, select_table_name), + DatabaseAndTableName(database_name, table_name)); }