1#include <Interpreters/InterpreterAlterQuery.h>
2#include <Interpreters/DDLWorker.h>
3#include <Interpreters/MutationsInterpreter.h>
4#include <Interpreters/AddDefaultDatabaseVisitor.h>
5#include <Interpreters/Context.h>
6#include <Parsers/ASTAlterQuery.h>
7#include <Storages/IStorage.h>
8#include <Storages/AlterCommands.h>
9#include <Storages/MutationCommands.h>
10#include <Storages/PartitionCommands.h>
11#include <Storages/LiveView/LiveViewCommands.h>
12#include <Storages/LiveView/StorageLiveView.h>
13#include <Common/typeid_cast.h>
14
15#include <algorithm>
16
17
18namespace DB
19{
20
21namespace ErrorCodes
22{
23 extern const int LOGICAL_ERROR;
24 extern const int ILLEGAL_COLUMN;
25 extern const int SUPPORT_IS_DISABLED;
26}
27
28
29InterpreterAlterQuery::InterpreterAlterQuery(const ASTPtr & query_ptr_, const Context & context_)
30 : query_ptr(query_ptr_), context(context_)
31{
32}
33
34BlockIO InterpreterAlterQuery::execute()
35{
36 const auto & alter = query_ptr->as<ASTAlterQuery &>();
37
38 if (!alter.cluster.empty())
39 return executeDDLQueryOnCluster(query_ptr, context, {alter.database});
40
41 const String & table_name = alter.table;
42 String database_name = alter.database.empty() ? context.getCurrentDatabase() : alter.database;
43 StoragePtr table = context.getTable(database_name, table_name);
44
45 /// Add default database to table identifiers that we can encounter in e.g. default expressions,
46 /// mutation expression, etc.
47 AddDefaultDatabaseVisitor visitor(database_name);
48 ASTPtr command_list_ptr = alter.command_list->ptr();
49 visitor.visit(command_list_ptr);
50
51 AlterCommands alter_commands;
52 PartitionCommands partition_commands;
53 MutationCommands mutation_commands;
54 LiveViewCommands live_view_commands;
55 for (ASTAlterCommand * command_ast : alter.command_list->commands)
56 {
57 if (auto alter_command = AlterCommand::parse(command_ast))
58 alter_commands.emplace_back(std::move(*alter_command));
59 else if (auto partition_command = PartitionCommand::parse(command_ast))
60 {
61 if (partition_command->type == PartitionCommand::DROP_DETACHED_PARTITION
62 && !context.getSettingsRef().allow_drop_detached)
63 throw DB::Exception("Cannot execute query: DROP DETACHED PART is disabled "
64 "(see allow_drop_detached setting)", ErrorCodes::SUPPORT_IS_DISABLED);
65 partition_commands.emplace_back(std::move(*partition_command));
66 }
67 else if (auto mut_command = MutationCommand::parse(command_ast))
68 mutation_commands.emplace_back(std::move(*mut_command));
69 else if (auto live_view_command = LiveViewCommand::parse(command_ast))
70 live_view_commands.emplace_back(std::move(*live_view_command));
71 else
72 throw Exception("Wrong parameter type in ALTER query", ErrorCodes::LOGICAL_ERROR);
73 }
74
75 if (!mutation_commands.empty())
76 {
77 auto table_lock_holder = table->lockStructureForShare(false /* because mutation is executed asyncronously */, context.getCurrentQueryId());
78 MutationsInterpreter(table, mutation_commands, context, false).validate(table_lock_holder);
79 table->mutate(mutation_commands, context);
80 }
81
82 if (!partition_commands.empty())
83 {
84 partition_commands.validate(*table);
85 table->alterPartition(query_ptr, partition_commands, context);
86 }
87
88 if (!live_view_commands.empty())
89 {
90 live_view_commands.validate(*table);
91 for (const LiveViewCommand & command : live_view_commands)
92 {
93 auto live_view = std::dynamic_pointer_cast<StorageLiveView>(table);
94 switch (command.type)
95 {
96 case LiveViewCommand::REFRESH:
97 live_view->refresh(context);
98 break;
99 }
100 }
101 }
102
103 if (!alter_commands.empty())
104 {
105 auto table_lock_holder = table->lockAlterIntention(context.getCurrentQueryId());
106 StorageInMemoryMetadata metadata = table->getInMemoryMetadata();
107 alter_commands.validate(metadata, context);
108 alter_commands.prepare(metadata, context);
109 table->checkAlterIsPossible(alter_commands, context.getSettingsRef());
110 table->alter(alter_commands, context, table_lock_holder);
111 }
112
113 return {};
114}
115
116}
117