diff --git a/dbms/src/Parsers/ASTAlterQuery.cpp b/dbms/src/Parsers/ASTAlterQuery.cpp index c7cd100b415..ccd45c94a3b 100644 --- a/dbms/src/Parsers/ASTAlterQuery.cpp +++ b/dbms/src/Parsers/ASTAlterQuery.cpp @@ -124,6 +124,26 @@ void ASTAlterCommand::formatImpl( << (part ? "PART " : "PARTITION ") << (settings.hilite ? hilite_none : ""); partition->formatImpl(settings, state, frame); } + else if (type == ASTAlterCommand::MOVE_PARTITION) + { + settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << "MOVE " + << (part ? "PART " : "PARTITION ") << (settings.hilite ? hilite_none : ""); + partition->formatImpl(settings, state, frame); + settings.ostr << "TO "; + switch (space_to_move) + { + case SpaceToMove::DISK: + settings.ostr << "DISK "; + break; + case SpaceToMove::VOLUME: + settings.ostr << "VOLUME "; + break; + case SpaceToMove::NONE: + default: + break; + } + settings.ostr << space_to_move_name; + } else if (type == ASTAlterCommand::REPLACE_PARTITION) { settings.ostr << (settings.hilite ? hilite_keyword : "") << indent_str << (replace ? "REPLACE" : "ATTACH") << " PARTITION " diff --git a/dbms/src/Parsers/ASTAlterQuery.h b/dbms/src/Parsers/ASTAlterQuery.h index 2c4b3ddbaf1..a29be885b6f 100644 --- a/dbms/src/Parsers/ASTAlterQuery.h +++ b/dbms/src/Parsers/ASTAlterQuery.h @@ -34,6 +34,7 @@ public: DROP_PARTITION, ATTACH_PARTITION, + MOVE_PARTITION, REPLACE_PARTITION, FETCH_PARTITION, FREEZE_PARTITION, @@ -69,7 +70,7 @@ public: /** The ADD INDEX query stores the name of the index following AFTER. * The DROP INDEX query stores the name for deletion. */ - ASTPtr index; + ASTPtr index; /** Used in DROP PARTITION and ATTACH PARTITION FROM queries. * The value or ID of the partition is stored here. @@ -98,6 +99,17 @@ public: bool if_exists = false; /// option for DROP_COLUMN, MODIFY_COLUMN, COMMENT_COLUMN + enum SpaceToMove + { + DISK, + VOLUME, + NONE, + }; + + SpaceToMove space_to_move = SpaceToMove::NONE; + + String space_to_move_name; + /** For FETCH PARTITION - the path in ZK to the shard, from which to download the partition. */ String from; diff --git a/dbms/src/Parsers/ParserAlterQuery.cpp b/dbms/src/Parsers/ParserAlterQuery.cpp index 98891bbdf5f..8b3e5bdee76 100644 --- a/dbms/src/Parsers/ParserAlterQuery.cpp +++ b/dbms/src/Parsers/ParserAlterQuery.cpp @@ -36,6 +36,7 @@ bool ParserAlterCommand::parseImpl(Pos & pos, ASTPtr & node, Expected & expected ParserKeyword s_detach_partition("DETACH PARTITION"); ParserKeyword s_drop_partition("DROP PARTITION"); ParserKeyword s_attach_part("ATTACH PART"); + ParserKeyword s_move_part("MOVE PART"); ParserKeyword s_fetch_partition("FETCH PARTITION"); ParserKeyword s_replace_partition("REPLACE PARTITION"); ParserKeyword s_freeze("FREEZE"); @@ -49,6 +50,9 @@ bool ParserAlterCommand::parseImpl(Pos & pos, ASTPtr & node, Expected & expected ParserKeyword s_with("WITH"); ParserKeyword s_name("NAME"); + ParserKeyword s_to_disk("TO DISK"); + ParserKeyword s_to_volume("TO VOLUME"); + ParserKeyword s_delete_where("DELETE WHERE"); ParserKeyword s_update("UPDATE"); ParserKeyword s_where("WHERE"); @@ -191,6 +195,26 @@ bool ParserAlterCommand::parseImpl(Pos & pos, ASTPtr & node, Expected & expected command->part = true; command->type = ASTAlterCommand::ATTACH_PARTITION; } + else if (s_move_part.ignore(pos, expected)) + { + if (!parser_string_literal.parse(pos, command->partition, expected)) + return false; + + command->type = ASTAlterCommand::MOVE_PARTITION; + + if (s_to_disk.ignore(pos)) + command->space_to_move = ASTAlterCommand::SpaceToMove::DISK; + else if (s_to_volume.ignore(pos)) + command->space_to_move = ASTAlterCommand::SpaceToMove::VOLUME; + else + return false; + + ASTPtr ast_space_name; + if (!parser_string_literal.parse(pos, ast_space_name, expected)) + return false; + + command->space_to_move_name = ast_space_name->as().value.get(); + } else if (s_fetch_partition.ignore(pos, expected)) { if (!parser_partition.parse(pos, command->partition, expected)) diff --git a/dbms/src/Storages/MergeTree/MergeTreeData.cpp b/dbms/src/Storages/MergeTree/MergeTreeData.cpp index aa8df87f04c..61aa515781a 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeData.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeData.cpp @@ -2571,6 +2571,13 @@ void MergeTreeData::freezePartition(const ASTPtr & partition_ast, const String & } +void MergeTreeData::movePartitionToDisk(const ASTPtr & partition, const String & name, const Context & /*context*/) +{ + String partition_id = partition->as().value.safeGet(); + move(partition_id, name); +} + + String MergeTreeData::getPartitionIDFromQuery(const ASTPtr & ast, const Context & context) { const auto & partition_ast = ast->as(); diff --git a/dbms/src/Storages/MergeTree/MergeTreeData.h b/dbms/src/Storages/MergeTree/MergeTreeData.h index 07b682d07d5..30b682e4942 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeData.h +++ b/dbms/src/Storages/MergeTree/MergeTreeData.h @@ -545,6 +545,9 @@ public: */ void freezePartition(const ASTPtr & partition, const String & with_name, const Context & context); + /// Moves partition to specified space + void movePartitionToDisk(const ASTPtr & partition, const String & name, const Context & context); + size_t getColumnCompressedSize(const std::string & name) const { auto lock = lockParts(); diff --git a/dbms/src/Storages/PartitionCommands.cpp b/dbms/src/Storages/PartitionCommands.cpp index f6aaee4c70e..1e6ce69d352 100644 --- a/dbms/src/Storages/PartitionCommands.cpp +++ b/dbms/src/Storages/PartitionCommands.cpp @@ -31,6 +31,27 @@ std::optional PartitionCommand::parse(const ASTAlterCommand * res.part = command_ast->part; return res; } + else if (command_ast->type == ASTAlterCommand::MOVE_PARTITION) + { + PartitionCommand res; + res.type = MOVE_PARTITION; + res.partition = command_ast->partition; + res.part = command_ast->part; + switch (command_ast->space_to_move) + { + case ASTAlterCommand::SpaceToMove::DISK: + res.space_to_move = PartitionCommand::SpaceToMove::DISK; + break; + case ASTAlterCommand::SpaceToMove::VOLUME: + res.space_to_move = PartitionCommand::SpaceToMove::VOLUME; + break; + case ASTAlterCommand::SpaceToMove::NONE: + res.space_to_move = PartitionCommand::SpaceToMove::NONE; + break; + } + res.space_to_move_name = command_ast->space_to_move_name; + return res; + } else if (command_ast->type == ASTAlterCommand::REPLACE_PARTITION) { PartitionCommand res; diff --git a/dbms/src/Storages/PartitionCommands.h b/dbms/src/Storages/PartitionCommands.h index 1f66c3f0c30..158c0cd2205 100644 --- a/dbms/src/Storages/PartitionCommands.h +++ b/dbms/src/Storages/PartitionCommands.h @@ -19,6 +19,7 @@ struct PartitionCommand enum Type { ATTACH_PARTITION, + MOVE_PARTITION, CLEAR_COLUMN, DROP_PARTITION, FETCH_PARTITION, @@ -49,6 +50,17 @@ struct PartitionCommand /// For FREEZE PARTITION String with_name; + enum SpaceToMove + { + DISK, + VOLUME, + NONE, + }; + + SpaceToMove space_to_move = SpaceToMove::NONE; + + String space_to_move_name; + static std::optional parse(const ASTAlterCommand * command); }; diff --git a/dbms/src/Storages/StorageMergeTree.cpp b/dbms/src/Storages/StorageMergeTree.cpp index b1879985433..c7576f09c0e 100644 --- a/dbms/src/Storages/StorageMergeTree.cpp +++ b/dbms/src/Storages/StorageMergeTree.cpp @@ -1060,6 +1060,10 @@ void StorageMergeTree::alterPartition(const ASTPtr & query, const PartitionComma attachPartition(command.partition, command.part, context); break; + case PartitionCommand::MOVE_PARTITION: + movePartitionToDisk(command.partition, command.space_to_move_name, context); + break; + case PartitionCommand::REPLACE_PARTITION: { checkPartitionCanBeDropped(command.partition); diff --git a/dbms/src/Storages/StorageReplicatedMergeTree.cpp b/dbms/src/Storages/StorageReplicatedMergeTree.cpp index 9cc83dd38ad..23aedc6bf96 100644 --- a/dbms/src/Storages/StorageReplicatedMergeTree.cpp +++ b/dbms/src/Storages/StorageReplicatedMergeTree.cpp @@ -3347,6 +3347,10 @@ void StorageReplicatedMergeTree::alterPartition(const ASTPtr & query, const Part attachPartition(command.partition, command.part, query_context); break; + case PartitionCommand::MOVE_PARTITION: + movePartitionToDisk(command.partition, command.space_to_move_name, query_context); + break; + case PartitionCommand::REPLACE_PARTITION: { checkPartitionCanBeDropped(command.partition);