1#include <Common/typeid_cast.h>
2#include <Parsers/ParserAlterQuery.h>
3#include <Parsers/CommonParsers.h>
4#include <Parsers/ExpressionElementParsers.h>
5#include <Parsers/ExpressionListParsers.h>
6#include <Parsers/ParserCreateQuery.h>
7#include <Parsers/ParserPartition.h>
8#include <Parsers/ParserSetQuery.h>
9#include <Parsers/ASTIdentifier.h>
10#include <Parsers/ASTIndexDeclaration.h>
11#include <Parsers/ASTAlterQuery.h>
12#include <Parsers/ASTLiteral.h>
13#include <Parsers/ASTAssignment.h>
14#include <Parsers/parseDatabaseAndTableName.h>
15
16
17namespace DB
18{
19
20bool ParserAlterCommand::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
21{
22 auto command = std::make_shared<ASTAlterCommand>();
23 node = command;
24
25 ParserKeyword s_add_column("ADD COLUMN");
26 ParserKeyword s_drop_column("DROP COLUMN");
27 ParserKeyword s_clear_column("CLEAR COLUMN");
28 ParserKeyword s_modify_column("MODIFY COLUMN");
29 ParserKeyword s_comment_column("COMMENT COLUMN");
30 ParserKeyword s_modify_order_by("MODIFY ORDER BY");
31 ParserKeyword s_modify_ttl("MODIFY TTL");
32 ParserKeyword s_modify_setting("MODIFY SETTING");
33
34 ParserKeyword s_add_index("ADD INDEX");
35 ParserKeyword s_drop_index("DROP INDEX");
36 ParserKeyword s_clear_index("CLEAR INDEX");
37 ParserKeyword s_materialize_index("MATERIALIZE INDEX");
38
39 ParserKeyword s_add_constraint("ADD CONSTRAINT");
40 ParserKeyword s_drop_constraint("DROP CONSTRAINT");
41
42 ParserKeyword s_add("ADD");
43 ParserKeyword s_drop("DROP");
44 ParserKeyword s_suspend("SUSPEND");
45 ParserKeyword s_resume("RESUME");
46 ParserKeyword s_refresh("REFRESH");
47 ParserKeyword s_modify("MODIFY");
48
49 ParserKeyword s_attach_partition("ATTACH PARTITION");
50 ParserKeyword s_detach_partition("DETACH PARTITION");
51 ParserKeyword s_drop_partition("DROP PARTITION");
52 ParserKeyword s_move_partition("MOVE PARTITION");
53 ParserKeyword s_drop_detached_partition("DROP DETACHED PARTITION");
54 ParserKeyword s_drop_detached_part("DROP DETACHED PART");
55 ParserKeyword s_attach_part("ATTACH PART");
56 ParserKeyword s_move_part("MOVE PART");
57 ParserKeyword s_fetch_partition("FETCH PARTITION");
58 ParserKeyword s_replace_partition("REPLACE PARTITION");
59 ParserKeyword s_freeze("FREEZE");
60 ParserKeyword s_partition("PARTITION");
61
62 ParserKeyword s_after("AFTER");
63 ParserKeyword s_if_not_exists("IF NOT EXISTS");
64 ParserKeyword s_if_exists("IF EXISTS");
65 ParserKeyword s_from("FROM");
66 ParserKeyword s_in_partition("IN PARTITION");
67 ParserKeyword s_with("WITH");
68 ParserKeyword s_name("NAME");
69
70 ParserKeyword s_to_disk("TO DISK");
71 ParserKeyword s_to_volume("TO VOLUME");
72
73 ParserKeyword s_delete_where("DELETE WHERE");
74 ParserKeyword s_update("UPDATE");
75 ParserKeyword s_where("WHERE");
76
77 ParserCompoundIdentifier parser_name;
78 ParserStringLiteral parser_string_literal;
79 ParserCompoundColumnDeclaration parser_col_decl;
80 ParserIndexDeclaration parser_idx_decl;
81 ParserConstraintDeclaration parser_constraint_decl;
82 ParserCompoundColumnDeclaration parser_modify_col_decl(false);
83 ParserPartition parser_partition;
84 ParserExpression parser_exp_elem;
85 ParserList parser_assignment_list(
86 std::make_unique<ParserAssignment>(), std::make_unique<ParserToken>(TokenType::Comma),
87 /* allow_empty = */ false);
88 ParserSetQuery parser_settings(true);
89 ParserNameList values_p;
90 ParserTTLExpressionList parser_ttl_list;
91
92 if (is_live_view)
93 {
94 if (s_refresh.ignore(pos, expected))
95 {
96 command->type = ASTAlterCommand::LIVE_VIEW_REFRESH;
97 }
98 else
99 return false;
100 }
101 else
102 {
103 if (s_add_column.ignore(pos, expected))
104 {
105 if (s_if_not_exists.ignore(pos, expected))
106 command->if_not_exists = true;
107
108 if (!parser_col_decl.parse(pos, command->col_decl, expected))
109 return false;
110
111 if (s_after.ignore(pos, expected))
112 {
113 if (!parser_name.parse(pos, command->column, expected))
114 return false;
115 }
116
117 command->type = ASTAlterCommand::ADD_COLUMN;
118 }
119 else if (s_drop_partition.ignore(pos, expected))
120 {
121 if (!parser_partition.parse(pos, command->partition, expected))
122 return false;
123
124 command->type = ASTAlterCommand::DROP_PARTITION;
125 }
126 else if (s_drop_detached_partition.ignore(pos, expected))
127 {
128 if (!parser_partition.parse(pos, command->partition, expected))
129 return false;
130
131 command->type = ASTAlterCommand::DROP_DETACHED_PARTITION;
132 }
133 else if (s_drop_detached_part.ignore(pos, expected))
134 {
135 if (!parser_string_literal.parse(pos, command->partition, expected))
136 return false;
137
138 command->type = ASTAlterCommand::DROP_DETACHED_PARTITION;
139 command->part = true;
140 }
141 else if (s_drop_column.ignore(pos, expected))
142 {
143 if (s_if_exists.ignore(pos, expected))
144 command->if_exists = true;
145
146 if (!parser_name.parse(pos, command->column, expected))
147 return false;
148
149 command->type = ASTAlterCommand::DROP_COLUMN;
150 command->detach = false;
151 }
152 else if (s_clear_column.ignore(pos, expected))
153 {
154 if (s_if_exists.ignore(pos, expected))
155 command->if_exists = true;
156
157 if (!parser_name.parse(pos, command->column, expected))
158 return false;
159
160 command->type = ASTAlterCommand::DROP_COLUMN;
161 command->clear_column = true;
162 command->detach = false;
163
164 if (s_in_partition.ignore(pos, expected))
165 {
166 if (!parser_partition.parse(pos, command->partition, expected))
167 return false;
168 }
169 }
170 else if (s_add_index.ignore(pos, expected))
171 {
172 if (s_if_not_exists.ignore(pos, expected))
173 command->if_not_exists = true;
174
175 if (!parser_idx_decl.parse(pos, command->index_decl, expected))
176 return false;
177
178 if (s_after.ignore(pos, expected))
179 {
180 if (!parser_name.parse(pos, command->index, expected))
181 return false;
182 }
183
184 command->type = ASTAlterCommand::ADD_INDEX;
185 }
186 else if (s_drop_index.ignore(pos, expected))
187 {
188 if (s_if_exists.ignore(pos, expected))
189 command->if_exists = true;
190
191 if (!parser_name.parse(pos, command->index, expected))
192 return false;
193
194 command->type = ASTAlterCommand::DROP_INDEX;
195 command->detach = false;
196 }
197 else if (s_clear_index.ignore(pos, expected))
198 {
199 if (s_if_exists.ignore(pos, expected))
200 command->if_exists = true;
201
202 if (!parser_name.parse(pos, command->index, expected))
203 return false;
204
205 command->type = ASTAlterCommand::DROP_INDEX;
206 command->clear_index = true;
207 command->detach = false;
208
209 if (!s_in_partition.ignore(pos, expected))
210 return false;
211 if (!parser_partition.parse(pos, command->partition, expected))
212 return false;
213 }
214 else if (s_materialize_index.ignore(pos, expected))
215 {
216 if (s_if_exists.ignore(pos, expected))
217 command->if_exists = true;
218
219 if (!parser_name.parse(pos, command->index, expected))
220 return false;
221
222 command->type = ASTAlterCommand::MATERIALIZE_INDEX;
223 command->detach = false;
224
225 if (s_in_partition.ignore(pos, expected))
226 {
227 if (!parser_partition.parse(pos, command->partition, expected))
228 return false;
229 }
230 }
231 else if (s_move_part.ignore(pos, expected))
232 {
233 if (!parser_string_literal.parse(pos, command->partition, expected))
234 return false;
235
236 command->type = ASTAlterCommand::MOVE_PARTITION;
237 command->part = true;
238
239 if (s_to_disk.ignore(pos))
240 command->move_destination_type = PartDestinationType::DISK;
241 else if (s_to_volume.ignore(pos))
242 command->move_destination_type = PartDestinationType::VOLUME;
243 else
244 return false;
245
246 ASTPtr ast_space_name;
247 if (!parser_string_literal.parse(pos, ast_space_name, expected))
248 return false;
249
250 command->move_destination_name = ast_space_name->as<ASTLiteral &>().value.get<const String &>();
251 }
252 else if (s_move_partition.ignore(pos, expected))
253 {
254 if (!parser_partition.parse(pos, command->partition, expected))
255 return false;
256
257 command->type = ASTAlterCommand::MOVE_PARTITION;
258
259 if (s_to_disk.ignore(pos))
260 command->move_destination_type = PartDestinationType::DISK;
261 else if (s_to_volume.ignore(pos))
262 command->move_destination_type = PartDestinationType::VOLUME;
263 else
264 return false;
265
266 ASTPtr ast_space_name;
267 if (!parser_string_literal.parse(pos, ast_space_name, expected))
268 return false;
269
270 command->move_destination_name = ast_space_name->as<ASTLiteral &>().value.get<const String &>();
271 }
272 else if (s_add_constraint.ignore(pos, expected))
273 {
274 if (s_if_not_exists.ignore(pos, expected))
275 command->if_not_exists = true;
276
277 if (!parser_constraint_decl.parse(pos, command->constraint_decl, expected))
278 return false;
279
280 command->type = ASTAlterCommand::ADD_CONSTRAINT;
281 }
282 else if (s_drop_constraint.ignore(pos, expected))
283 {
284 if (s_if_exists.ignore(pos, expected))
285 command->if_exists = true;
286
287 if (!parser_name.parse(pos, command->constraint, expected))
288 return false;
289
290 command->type = ASTAlterCommand::DROP_CONSTRAINT;
291 command->detach = false;
292 }
293 else if (s_detach_partition.ignore(pos, expected))
294 {
295 if (!parser_partition.parse(pos, command->partition, expected))
296 return false;
297
298 command->type = ASTAlterCommand::DROP_PARTITION;
299 command->detach = true;
300 }
301 else if (s_attach_partition.ignore(pos, expected))
302 {
303 if (!parser_partition.parse(pos, command->partition, expected))
304 return false;
305
306 if (s_from.ignore(pos))
307 {
308 if (!parseDatabaseAndTableName(pos, expected, command->from_database, command->from_table))
309 return false;
310
311 command->replace = false;
312 command->type = ASTAlterCommand::REPLACE_PARTITION;
313 }
314 else
315 {
316 command->type = ASTAlterCommand::ATTACH_PARTITION;
317 }
318 }
319 else if (s_replace_partition.ignore(pos, expected))
320 {
321 if (!parser_partition.parse(pos, command->partition, expected))
322 return false;
323
324 if (!s_from.ignore(pos, expected))
325 return false;
326
327 if (!parseDatabaseAndTableName(pos, expected, command->from_database, command->from_table))
328 return false;
329
330 command->replace = true;
331 command->type = ASTAlterCommand::REPLACE_PARTITION;
332 }
333 else if (s_attach_part.ignore(pos, expected))
334 {
335 if (!parser_string_literal.parse(pos, command->partition, expected))
336 return false;
337
338 command->part = true;
339 command->type = ASTAlterCommand::ATTACH_PARTITION;
340 }
341 else if (s_fetch_partition.ignore(pos, expected))
342 {
343 if (!parser_partition.parse(pos, command->partition, expected))
344 return false;
345
346 if (!s_from.ignore(pos, expected))
347 return false;
348
349 ASTPtr ast_from;
350 if (!parser_string_literal.parse(pos, ast_from, expected))
351 return false;
352
353 command->from = ast_from->as<ASTLiteral &>().value.get<const String &>();
354 command->type = ASTAlterCommand::FETCH_PARTITION;
355 }
356 else if (s_freeze.ignore(pos, expected))
357 {
358 if (s_partition.ignore(pos, expected))
359 {
360 if (!parser_partition.parse(pos, command->partition, expected))
361 return false;
362
363 command->type = ASTAlterCommand::FREEZE_PARTITION;
364 }
365 else
366 {
367 command->type = ASTAlterCommand::FREEZE_ALL;
368 }
369
370 /// WITH NAME 'name' - place local backup to directory with specified name
371 if (s_with.ignore(pos, expected))
372 {
373 if (!s_name.ignore(pos, expected))
374 return false;
375
376 ASTPtr ast_with_name;
377 if (!parser_string_literal.parse(pos, ast_with_name, expected))
378 return false;
379
380 command->with_name = ast_with_name->as<ASTLiteral &>().value.get<const String &>();
381 }
382 }
383 else if (s_modify_column.ignore(pos, expected))
384 {
385 if (s_if_exists.ignore(pos, expected))
386 command->if_exists = true;
387
388 if (!parser_modify_col_decl.parse(pos, command->col_decl, expected))
389 return false;
390
391 command->type = ASTAlterCommand::MODIFY_COLUMN;
392 }
393 else if (s_modify_order_by.ignore(pos, expected))
394 {
395 if (!parser_exp_elem.parse(pos, command->order_by, expected))
396 return false;
397
398 command->type = ASTAlterCommand::MODIFY_ORDER_BY;
399 }
400 else if (s_delete_where.ignore(pos, expected))
401 {
402 if (!parser_exp_elem.parse(pos, command->predicate, expected))
403 return false;
404
405 command->type = ASTAlterCommand::DELETE;
406 }
407 else if (s_update.ignore(pos, expected))
408 {
409 if (!parser_assignment_list.parse(pos, command->update_assignments, expected))
410 return false;
411
412 if (!s_where.ignore(pos, expected))
413 return false;
414
415 if (!parser_exp_elem.parse(pos, command->predicate, expected))
416 return false;
417
418 command->type = ASTAlterCommand::UPDATE;
419 }
420 else if (s_comment_column.ignore(pos, expected))
421 {
422 if (s_if_exists.ignore(pos, expected))
423 command->if_exists = true;
424
425 if (!parser_name.parse(pos, command->column, expected))
426 return false;
427
428 if (!parser_string_literal.parse(pos, command->comment, expected))
429 return false;
430
431 command->type = ASTAlterCommand::COMMENT_COLUMN;
432 }
433 else if (s_modify_ttl.ignore(pos, expected))
434 {
435 if (!parser_ttl_list.parse(pos, command->ttl, expected))
436 return false;
437 command->type = ASTAlterCommand::MODIFY_TTL;
438 }
439 else if (s_modify_setting.ignore(pos, expected))
440 {
441 if (!parser_settings.parse(pos, command->settings_changes, expected))
442 return false;
443 command->type = ASTAlterCommand::MODIFY_SETTING;
444 }
445 else
446 return false;
447
448 }
449
450 if (command->col_decl)
451 command->children.push_back(command->col_decl);
452 if (command->column)
453 command->children.push_back(command->column);
454 if (command->partition)
455 command->children.push_back(command->partition);
456 if (command->order_by)
457 command->children.push_back(command->order_by);
458 if (command->predicate)
459 command->children.push_back(command->predicate);
460 if (command->update_assignments)
461 command->children.push_back(command->update_assignments);
462 if (command->values)
463 command->children.push_back(command->values);
464 if (command->comment)
465 command->children.push_back(command->comment);
466 if (command->ttl)
467 command->children.push_back(command->ttl);
468 if (command->settings_changes)
469 command->children.push_back(command->settings_changes);
470
471 return true;
472}
473
474
475bool ParserAlterCommandList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
476{
477 auto command_list = std::make_shared<ASTAlterCommandList>();
478 node = command_list;
479
480 ParserToken s_comma(TokenType::Comma);
481 ParserAlterCommand p_command(is_live_view);
482
483 do
484 {
485 ASTPtr command;
486 if (!p_command.parse(pos, command, expected))
487 return false;
488
489 command_list->add(command);
490 }
491 while (s_comma.ignore(pos, expected));
492
493 return true;
494}
495
496
497bool ParserAssignment::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
498{
499 auto assignment = std::make_shared<ASTAssignment>();
500 node = assignment;
501
502 ParserIdentifier p_identifier;
503 ParserToken s_equals(TokenType::Equals);
504 ParserExpression p_expression;
505
506 ASTPtr column;
507 if (!p_identifier.parse(pos, column, expected))
508 return false;
509
510 if (!s_equals.ignore(pos, expected))
511 return false;
512
513 if (!p_expression.parse(pos, assignment->expression, expected))
514 return false;
515
516 tryGetIdentifierNameInto(column, assignment->column_name);
517 if (assignment->expression)
518 assignment->children.push_back(assignment->expression);
519
520 return true;
521}
522
523
524bool ParserAlterQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
525{
526 auto query = std::make_shared<ASTAlterQuery>();
527 node = query;
528
529 ParserKeyword s_alter_table("ALTER TABLE");
530 ParserKeyword s_alter_live_view("ALTER LIVE VIEW");
531
532 bool is_live_view = false;
533
534 if (!s_alter_table.ignore(pos, expected))
535 {
536 if (!s_alter_live_view.ignore(pos, expected))
537 return false;
538 else
539 is_live_view = true;
540 }
541
542 if (is_live_view)
543 query->is_live_view = true;
544
545 if (!parseDatabaseAndTableName(pos, expected, query->database, query->table))
546 return false;
547
548 String cluster_str;
549 if (ParserKeyword{"ON"}.ignore(pos, expected))
550 {
551 if (!ASTQueryWithOnCluster::parse(pos, cluster_str, expected))
552 return false;
553 }
554 query->cluster = cluster_str;
555
556 ParserAlterCommandList p_command_list(is_live_view);
557 ASTPtr command_list;
558 if (!p_command_list.parse(pos, command_list, expected))
559 return false;
560
561 query->set(query->command_list, command_list);
562
563 return true;
564}
565
566}
567