1 | #include <Parsers/ASTAlterQuery.h> |
2 | #include <iomanip> |
3 | #include <Common/quoteString.h> |
4 | |
5 | |
6 | namespace DB |
7 | { |
8 | |
9 | namespace ErrorCodes |
10 | { |
11 | extern const int UNEXPECTED_AST_STRUCTURE; |
12 | } |
13 | |
14 | ASTPtr ASTAlterCommand::clone() const |
15 | { |
16 | auto res = std::make_shared<ASTAlterCommand>(*this); |
17 | res->children.clear(); |
18 | |
19 | if (col_decl) |
20 | { |
21 | res->col_decl = col_decl->clone(); |
22 | res->children.push_back(res->col_decl); |
23 | } |
24 | if (column) |
25 | { |
26 | res->column = column->clone(); |
27 | res->children.push_back(res->column); |
28 | } |
29 | if (order_by) |
30 | { |
31 | res->order_by = order_by->clone(); |
32 | res->children.push_back(res->order_by); |
33 | } |
34 | if (partition) |
35 | { |
36 | res->partition = partition->clone(); |
37 | res->children.push_back(res->partition); |
38 | } |
39 | if (predicate) |
40 | { |
41 | res->predicate = predicate->clone(); |
42 | res->children.push_back(res->predicate); |
43 | } |
44 | if (ttl) |
45 | { |
46 | res->ttl = ttl->clone(); |
47 | res->children.push_back(res->ttl); |
48 | } |
49 | if (settings_changes) |
50 | { |
51 | res->settings_changes = settings_changes->clone(); |
52 | res->children.push_back(res->settings_changes); |
53 | } |
54 | if (values) |
55 | { |
56 | res->values = values->clone(); |
57 | res->children.push_back(res->values); |
58 | } |
59 | |
60 | return res; |
61 | } |
62 | |
63 | void ASTAlterCommand::formatImpl( |
64 | const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const |
65 | { |
66 | std::string indent_str = settings.one_line ? "" : std::string(4 * frame.indent, ' '); |
67 | |
68 | if (type == ASTAlterCommand::ADD_COLUMN) |
69 | { |
70 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "ADD COLUMN " << (if_not_exists ? "IF NOT EXISTS " : "" ) << (settings.hilite ? hilite_none : "" ); |
71 | col_decl->formatImpl(settings, state, frame); |
72 | |
73 | /// AFTER |
74 | if (column) |
75 | { |
76 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << " AFTER " << (settings.hilite ? hilite_none : "" ); |
77 | column->formatImpl(settings, state, frame); |
78 | } |
79 | } |
80 | else if (type == ASTAlterCommand::DROP_COLUMN) |
81 | { |
82 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str |
83 | << (clear_column ? "CLEAR " : "DROP " ) << "COLUMN " << (if_exists ? "IF EXISTS " : "" ) << (settings.hilite ? hilite_none : "" ); |
84 | column->formatImpl(settings, state, frame); |
85 | if (partition) |
86 | { |
87 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str<< " IN PARTITION " << (settings.hilite ? hilite_none : "" ); |
88 | partition->formatImpl(settings, state, frame); |
89 | } |
90 | } |
91 | else if (type == ASTAlterCommand::MODIFY_COLUMN) |
92 | { |
93 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "MODIFY COLUMN " << (if_exists ? "IF EXISTS " : "" ) << (settings.hilite ? hilite_none : "" ); |
94 | col_decl->formatImpl(settings, state, frame); |
95 | } |
96 | else if (type == ASTAlterCommand::COMMENT_COLUMN) |
97 | { |
98 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "COMMENT COLUMN " << (if_exists ? "IF EXISTS " : "" ) << (settings.hilite ? hilite_none : "" ); |
99 | column->formatImpl(settings, state, frame); |
100 | settings.ostr << " " << (settings.hilite ? hilite_none : "" ); |
101 | comment->formatImpl(settings, state, frame); |
102 | } |
103 | else if (type == ASTAlterCommand::MODIFY_ORDER_BY) |
104 | { |
105 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "MODIFY ORDER BY " << (settings.hilite ? hilite_none : "" ); |
106 | order_by->formatImpl(settings, state, frame); |
107 | } |
108 | else if (type == ASTAlterCommand::ADD_INDEX) |
109 | { |
110 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "ADD INDEX " << (if_not_exists ? "IF NOT EXISTS " : "" ) << (settings.hilite ? hilite_none : "" ); |
111 | index_decl->formatImpl(settings, state, frame); |
112 | |
113 | /// AFTER |
114 | if (index) |
115 | { |
116 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << " AFTER " << (settings.hilite ? hilite_none : "" ); |
117 | index->formatImpl(settings, state, frame); |
118 | } |
119 | } |
120 | else if (type == ASTAlterCommand::DROP_INDEX) |
121 | { |
122 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str |
123 | << (clear_index ? "CLEAR " : "DROP " ) << "INDEX " << (if_exists ? "IF EXISTS " : "" ) << (settings.hilite ? hilite_none : "" ); |
124 | index->formatImpl(settings, state, frame); |
125 | if (partition) |
126 | { |
127 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str<< " IN PARTITION " << (settings.hilite ? hilite_none : "" ); |
128 | partition->formatImpl(settings, state, frame); |
129 | } |
130 | } |
131 | else if (type == ASTAlterCommand::MATERIALIZE_INDEX) |
132 | { |
133 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str |
134 | << "MATERIALIZE INDEX " << (settings.hilite ? hilite_none : "" ); |
135 | index->formatImpl(settings, state, frame); |
136 | if (partition) |
137 | { |
138 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str<< " IN PARTITION " << (settings.hilite ? hilite_none : "" ); |
139 | partition->formatImpl(settings, state, frame); |
140 | } |
141 | } |
142 | else if (type == ASTAlterCommand::ADD_CONSTRAINT) |
143 | { |
144 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "ADD CONSTRAINT" << (if_not_exists ? "IF NOT EXISTS " : "" ) << (settings.hilite ? hilite_none : "" ); |
145 | constraint_decl->formatImpl(settings, state, frame); |
146 | } |
147 | else if (type == ASTAlterCommand::DROP_CONSTRAINT) |
148 | { |
149 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str |
150 | << "DROP CONSTRAINT " << (if_exists ? "IF EXISTS " : "" ) << (settings.hilite ? hilite_none : "" ); |
151 | constraint->formatImpl(settings, state, frame); |
152 | } |
153 | else if (type == ASTAlterCommand::DROP_PARTITION) |
154 | { |
155 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << (detach ? "DETACH" : "DROP" ) << " PARTITION " |
156 | << (settings.hilite ? hilite_none : "" ); |
157 | partition->formatImpl(settings, state, frame); |
158 | } |
159 | else if (type == ASTAlterCommand::DROP_DETACHED_PARTITION) |
160 | { |
161 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "DROP DETACHED" << (part ? " PART " : " PARTITION " ) |
162 | << (settings.hilite ? hilite_none : "" ); |
163 | partition->formatImpl(settings, state, frame); |
164 | } |
165 | else if (type == ASTAlterCommand::ATTACH_PARTITION) |
166 | { |
167 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "ATTACH " |
168 | << (part ? "PART " : "PARTITION " ) << (settings.hilite ? hilite_none : "" ); |
169 | partition->formatImpl(settings, state, frame); |
170 | } |
171 | else if (type == ASTAlterCommand::MOVE_PARTITION) |
172 | { |
173 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "MOVE " |
174 | << (part ? "PART " : "PARTITION " ) << (settings.hilite ? hilite_none : "" ); |
175 | partition->formatImpl(settings, state, frame); |
176 | settings.ostr << " TO " ; |
177 | switch (move_destination_type) |
178 | { |
179 | case PartDestinationType::DISK: |
180 | settings.ostr << "DISK " ; |
181 | break; |
182 | case PartDestinationType::VOLUME: |
183 | settings.ostr << "VOLUME " ; |
184 | break; |
185 | default: |
186 | break; |
187 | } |
188 | settings.ostr << quoteString(move_destination_name); |
189 | } |
190 | else if (type == ASTAlterCommand::REPLACE_PARTITION) |
191 | { |
192 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << (replace ? "REPLACE" : "ATTACH" ) << " PARTITION " |
193 | << (settings.hilite ? hilite_none : "" ); |
194 | partition->formatImpl(settings, state, frame); |
195 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << " FROM " << (settings.hilite ? hilite_none : "" ); |
196 | if (!from_database.empty()) |
197 | { |
198 | settings.ostr << (settings.hilite ? hilite_identifier : "" ) << backQuoteIfNeed(from_database) |
199 | << (settings.hilite ? hilite_none : "" ) << "." ; |
200 | } |
201 | settings.ostr << (settings.hilite ? hilite_identifier : "" ) << backQuoteIfNeed(from_table) << (settings.hilite ? hilite_none : "" ); |
202 | } |
203 | else if (type == ASTAlterCommand::FETCH_PARTITION) |
204 | { |
205 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "FETCH " |
206 | << "PARTITION " << (settings.hilite ? hilite_none : "" ); |
207 | partition->formatImpl(settings, state, frame); |
208 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) |
209 | << " FROM " << (settings.hilite ? hilite_none : "" ) << std::quoted(from, '\''); |
210 | } |
211 | else if (type == ASTAlterCommand::FREEZE_PARTITION) |
212 | { |
213 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "FREEZE PARTITION " << (settings.hilite ? hilite_none : "" ); |
214 | partition->formatImpl(settings, state, frame); |
215 | |
216 | if (!with_name.empty()) |
217 | { |
218 | settings.ostr << " " << (settings.hilite ? hilite_keyword : "" ) << "WITH NAME" << (settings.hilite ? hilite_none : "" ) |
219 | << " " << std::quoted(with_name, '\''); |
220 | } |
221 | } |
222 | else if (type == ASTAlterCommand::FREEZE_ALL) |
223 | { |
224 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "FREEZE" ; |
225 | |
226 | if (!with_name.empty()) |
227 | { |
228 | settings.ostr << " " << (settings.hilite ? hilite_keyword : "" ) << "WITH NAME" << (settings.hilite ? hilite_none : "" ) |
229 | << " " << std::quoted(with_name, '\''); |
230 | } |
231 | } |
232 | else if (type == ASTAlterCommand::DELETE) |
233 | { |
234 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "DELETE WHERE " << (settings.hilite ? hilite_none : "" ); |
235 | predicate->formatImpl(settings, state, frame); |
236 | } |
237 | else if (type == ASTAlterCommand::UPDATE) |
238 | { |
239 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "UPDATE " << (settings.hilite ? hilite_none : "" ); |
240 | update_assignments->formatImpl(settings, state, frame); |
241 | |
242 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << " WHERE " << (settings.hilite ? hilite_none : "" ); |
243 | predicate->formatImpl(settings, state, frame); |
244 | } |
245 | else if (type == ASTAlterCommand::MODIFY_TTL) |
246 | { |
247 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "MODIFY TTL " << (settings.hilite ? hilite_none : "" ); |
248 | ttl->formatImpl(settings, state, frame); |
249 | } |
250 | else if (type == ASTAlterCommand::MODIFY_SETTING) |
251 | { |
252 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "MODIFY SETTING " << (settings.hilite ? hilite_none : "" ); |
253 | settings_changes->formatImpl(settings, state, frame); |
254 | } |
255 | else if (type == ASTAlterCommand::LIVE_VIEW_REFRESH) |
256 | { |
257 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "REFRESH " << (settings.hilite ? hilite_none : "" ); |
258 | } |
259 | else |
260 | throw Exception("Unexpected type of ALTER" , ErrorCodes::UNEXPECTED_AST_STRUCTURE); |
261 | } |
262 | |
263 | |
264 | ASTPtr ASTAlterCommandList::clone() const |
265 | { |
266 | auto res = std::make_shared<ASTAlterCommandList>(); |
267 | for (ASTAlterCommand * command : commands) |
268 | res->add(command->clone()); |
269 | return res; |
270 | } |
271 | |
272 | void ASTAlterCommandList::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const |
273 | { |
274 | std::string indent_str = settings.one_line ? "" : std::string(4 * frame.indent, ' '); |
275 | |
276 | for (size_t i = 0; i < commands.size(); ++i) |
277 | { |
278 | static_cast<IAST *>(commands[i])->formatImpl(settings, state, frame); |
279 | |
280 | std::string comma = (i < (commands.size() - 1)) ? "," : "" ; |
281 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << comma << (settings.hilite ? hilite_none : "" ); |
282 | |
283 | settings.ostr << settings.nl_or_ws; |
284 | } |
285 | } |
286 | |
287 | |
288 | /** Get the text that identifies this element. */ |
289 | String ASTAlterQuery::getID(char delim) const |
290 | { |
291 | return "AlterQuery" + (delim + database) + delim + table; |
292 | } |
293 | |
294 | ASTPtr ASTAlterQuery::clone() const |
295 | { |
296 | auto res = std::make_shared<ASTAlterQuery>(*this); |
297 | res->children.clear(); |
298 | |
299 | if (command_list) |
300 | res->set(res->command_list, command_list->clone()); |
301 | |
302 | return res; |
303 | } |
304 | |
305 | void ASTAlterQuery::formatQueryImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const |
306 | { |
307 | frame.need_parens = false; |
308 | |
309 | std::string indent_str = settings.one_line ? "" : std::string(4u * frame.indent, ' '); |
310 | |
311 | if (is_live_view) |
312 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "ALTER LIVE VIEW " << (settings.hilite ? hilite_none : "" ); |
313 | else |
314 | settings.ostr << (settings.hilite ? hilite_keyword : "" ) << indent_str << "ALTER TABLE " << (settings.hilite ? hilite_none : "" ); |
315 | |
316 | if (!table.empty()) |
317 | { |
318 | if (!database.empty()) |
319 | { |
320 | settings.ostr << indent_str << backQuoteIfNeed(database); |
321 | settings.ostr << "." ; |
322 | } |
323 | settings.ostr << indent_str << backQuoteIfNeed(table); |
324 | } |
325 | formatOnCluster(settings); |
326 | settings.ostr << settings.nl_or_ws; |
327 | |
328 | FormatStateStacked frame_nested = frame; |
329 | frame_nested.need_parens = false; |
330 | ++frame_nested.indent; |
331 | static_cast<IAST *>(command_list)->formatImpl(settings, state, frame_nested); |
332 | } |
333 | |
334 | } |
335 | |