diff --git a/src/Databases/DatabaseAtomic.cpp b/src/Databases/DatabaseAtomic.cpp index 7a54234cb06..66183f450fb 100644 --- a/src/Databases/DatabaseAtomic.cpp +++ b/src/Databases/DatabaseAtomic.cpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace DB @@ -111,6 +112,7 @@ void DatabaseAtomic::renameTable(const Context & context, const String & table_n return; } auto & other_db = dynamic_cast(to_database); + bool inside_database = this == &other_db; String old_metadata_path = getObjectMetadataPath(table_name); String new_metadata_path = to_database.getObjectMetadataPath(to_table_name); @@ -131,10 +133,18 @@ void DatabaseAtomic::renameTable(const Context & context, const String & table_n tryCreateSymlink(table_name_, table_data_path_); }; + auto assertCanMoveMatView = [&](const StoragePtr & table_) + { + if (inside_database) + return; + if (const auto * mv = dynamic_cast(table_.get())) + if (mv->hasInnerTable()) + throw Exception("Cannot move MaterializedView with inner table to other database", ErrorCodes::NOT_IMPLEMENTED); + }; + String table_data_path; String other_table_data_path; - bool inside_database = this == &other_db; if (inside_database && table_name == to_table_name) return; @@ -154,9 +164,13 @@ void DatabaseAtomic::renameTable(const Context & context, const String & table_n } StoragePtr table = getTableUnlocked(table_name); + assertCanMoveMatView(table); StoragePtr other_table; if (exchange) + { other_table = other_db.getTableUnlocked(to_table_name); + assertCanMoveMatView(other_table); + } if (exchange) renameExchange(old_metadata_path, new_metadata_path); diff --git a/src/Storages/StorageMaterializedView.cpp b/src/Storages/StorageMaterializedView.cpp index ec7831c706a..35e7b59e1ab 100644 --- a/src/Storages/StorageMaterializedView.cpp +++ b/src/Storages/StorageMaterializedView.cpp @@ -330,33 +330,28 @@ void StorageMaterializedView::mutate(const MutationCommands & commands, const Co void StorageMaterializedView::renameInMemory(const StorageID & new_table_id) { auto old_table_id = getStorageID(); + bool from_atomic_to_atomic_database = old_table_id.hasUUID() && new_table_id.hasUUID(); - if (has_inner_table && tryGetTargetTable()) + if (has_inner_table && tryGetTargetTable() && !from_atomic_to_atomic_database) { - auto old_target_table_name = generateInnerTableName(old_table_id); auto new_target_table_name = generateInnerTableName(new_table_id); - if (old_table_id.database_name != new_table_id.database_name || - old_target_table_name != new_target_table_name) - { + auto rename = std::make_shared(); - auto rename = std::make_shared(); + ASTRenameQuery::Table from; + from.database = target_table_id.database_name; + from.table = target_table_id.table_name; - ASTRenameQuery::Table from; - from.database = target_table_id.database_name; - from.table = target_table_id.table_name; + ASTRenameQuery::Table to; + to.database = target_table_id.database_name; + to.table = new_target_table_name; - ASTRenameQuery::Table to; - to.database = target_table_id.database_name; - to.table = new_target_table_name; + ASTRenameQuery::Element elem; + elem.from = from; + elem.to = to; + rename->elements.emplace_back(elem); - ASTRenameQuery::Element elem; - elem.from = from; - elem.to = to; - rename->elements.emplace_back(elem); - - InterpreterRenameQuery(rename, global_context).execute(); - target_table_id.table_name = new_target_table_name; - } + InterpreterRenameQuery(rename, global_context).execute(); + target_table_id.table_name = new_target_table_name; } IStorage::renameInMemory(new_table_id); diff --git a/src/Storages/StorageMaterializedView.h b/src/Storages/StorageMaterializedView.h index 175529fd940..97496d33f94 100644 --- a/src/Storages/StorageMaterializedView.h +++ b/src/Storages/StorageMaterializedView.h @@ -21,6 +21,7 @@ public: ASTPtr getSelectQuery() const { return select->clone(); } ASTPtr getInnerQuery() const { return inner_query->clone(); } + bool hasInnerTable() const { return has_inner_table; } NameAndTypePair getColumn(const String & column_name) const override; bool hasColumn(const String & column_name) const override;