1#include <Storages/PartitionCommands.h>
2#include <Storages/IStorage.h>
3#include <Storages/MergeTree/PartDestinationType.h>
4#include <Parsers/ASTAlterQuery.h>
5#include <Parsers/ASTIdentifier.h>
6
7
8namespace DB
9{
10
11namespace ErrorCodes
12{
13 extern const int BAD_ARGUMENTS;
14 extern const int ILLEGAL_COLUMN;
15}
16
17std::optional<PartitionCommand> PartitionCommand::parse(const ASTAlterCommand * command_ast)
18{
19 if (command_ast->type == ASTAlterCommand::DROP_PARTITION)
20 {
21 PartitionCommand res;
22 res.type = DROP_PARTITION;
23 res.partition = command_ast->partition;
24 res.detach = command_ast->detach;
25 return res;
26 }
27 else if (command_ast->type == ASTAlterCommand::DROP_DETACHED_PARTITION)
28 {
29 PartitionCommand res;
30 res.type = DROP_DETACHED_PARTITION;
31 res.partition = command_ast->partition;
32 res.part = command_ast->part;
33 return res;
34 }
35 else if (command_ast->type == ASTAlterCommand::ATTACH_PARTITION)
36 {
37 PartitionCommand res;
38 res.type = ATTACH_PARTITION;
39 res.partition = command_ast->partition;
40 res.part = command_ast->part;
41 return res;
42 }
43 else if (command_ast->type == ASTAlterCommand::MOVE_PARTITION)
44 {
45 PartitionCommand res;
46 res.type = MOVE_PARTITION;
47 res.partition = command_ast->partition;
48 res.part = command_ast->part;
49 switch (command_ast->move_destination_type)
50 {
51 case PartDestinationType::DISK:
52 res.move_destination_type = PartitionCommand::MoveDestinationType::DISK;
53 break;
54 case PartDestinationType::VOLUME:
55 res.move_destination_type = PartitionCommand::MoveDestinationType::VOLUME;
56 break;
57 default:
58 break;
59 }
60 res.move_destination_name = command_ast->move_destination_name;
61 return res;
62 }
63 else if (command_ast->type == ASTAlterCommand::REPLACE_PARTITION)
64 {
65 PartitionCommand res;
66 res.type = REPLACE_PARTITION;
67 res.partition = command_ast->partition;
68 res.replace = command_ast->replace;
69 res.from_database = command_ast->from_database;
70 res.from_table = command_ast->from_table;
71 return res;
72 }
73 else if (command_ast->type == ASTAlterCommand::FETCH_PARTITION)
74 {
75 PartitionCommand res;
76 res.type = FETCH_PARTITION;
77 res.partition = command_ast->partition;
78 res.from_zookeeper_path = command_ast->from;
79 return res;
80 }
81 else if (command_ast->type == ASTAlterCommand::FREEZE_PARTITION)
82 {
83 PartitionCommand res;
84 res.type = FREEZE_PARTITION;
85 res.partition = command_ast->partition;
86 res.with_name = command_ast->with_name;
87 return res;
88 }
89 else if (command_ast->type == ASTAlterCommand::DROP_COLUMN && command_ast->partition)
90 {
91 if (!command_ast->clear_column)
92 throw Exception("Can't DROP COLUMN from partition. It is possible only to CLEAR COLUMN in partition", ErrorCodes::BAD_ARGUMENTS);
93
94 PartitionCommand res;
95 res.type = CLEAR_COLUMN;
96 res.partition = command_ast->partition;
97 res.column_name = getIdentifierName(command_ast->column);
98 return res;
99 }
100 else if (command_ast->type == ASTAlterCommand::DROP_INDEX && command_ast->partition)
101 {
102 if (!command_ast->clear_index)
103 throw Exception("Can't DROP INDEX from partition. It is possible only to CLEAR INDEX in partition", ErrorCodes::BAD_ARGUMENTS);
104
105 PartitionCommand res;
106 res.type = CLEAR_INDEX;
107 res.partition = command_ast->partition;
108 res.index_name = getIdentifierName(command_ast->index);
109 return res;
110 }
111 else if (command_ast->type == ASTAlterCommand::FREEZE_ALL)
112 {
113 PartitionCommand command;
114 command.type = PartitionCommand::FREEZE_ALL_PARTITIONS;
115 command.with_name = command_ast->with_name;
116 return command;
117 }
118 else
119 return {};
120}
121
122void PartitionCommands::validate(const IStorage & table)
123{
124 for (const PartitionCommand & command : *this)
125 {
126 if (command.type == PartitionCommand::CLEAR_COLUMN)
127 {
128 String column_name = command.column_name.safeGet<String>();
129
130 if (!table.getColumns().hasPhysical(column_name))
131 {
132 throw Exception("Wrong column name. Cannot find column " + column_name + " to clear it from partition",
133 DB::ErrorCodes::ILLEGAL_COLUMN);
134 }
135 }
136 else if (command.type == PartitionCommand::CLEAR_INDEX)
137 {
138 String index_name = command.index_name.safeGet<String>();
139
140 if (!table.getIndices().has(index_name))
141 {
142 throw Exception("Wrong index name. Cannot find index " + index_name + " to clear it from partition",
143 DB::ErrorCodes::BAD_ARGUMENTS);
144 }
145 }
146 }
147}
148
149}
150