1#pragma once
2
3#include <optional>
4#include <Core/NamesAndTypes.h>
5#include <Storages/IStorage_fwd.h>
6#include <Storages/StorageInMemoryMetadata.h>
7
8
9#include <Common/SettingsChanges.h>
10
11
12namespace DB
13{
14
15class ASTAlterCommand;
16
17/// Operation from the ALTER query (except for manipulation with PART/PARTITION).
18/// Adding Nested columns is not expanded to add individual columns.
19struct AlterCommand
20{
21 enum Type
22 {
23 ADD_COLUMN,
24 DROP_COLUMN,
25 MODIFY_COLUMN,
26 COMMENT_COLUMN,
27 MODIFY_ORDER_BY,
28 ADD_INDEX,
29 DROP_INDEX,
30 ADD_CONSTRAINT,
31 DROP_CONSTRAINT,
32 MODIFY_TTL,
33 MODIFY_SETTING,
34 };
35
36 Type type;
37
38 String column_name;
39
40 /// For DROP COLUMN ... FROM PARTITION
41 String partition_name;
42
43 /// For ADD and MODIFY, a new column type.
44 DataTypePtr data_type = nullptr;
45
46 ColumnDefaultKind default_kind{};
47 ASTPtr default_expression{};
48
49 /// For COMMENT column
50 std::optional<String> comment;
51
52 /// For ADD - after which column to add a new one. If an empty string, add to the end. To add to the beginning now it is impossible.
53 String after_column;
54
55 /// For DROP_COLUMN, MODIFY_COLUMN, COMMENT_COLUMN
56 bool if_exists = false;
57
58 /// For ADD_COLUMN
59 bool if_not_exists = false;
60
61 /// For MODIFY_ORDER_BY
62 ASTPtr order_by = nullptr;
63
64 /// For ADD INDEX
65 ASTPtr index_decl = nullptr;
66 String after_index_name;
67
68 /// For ADD/DROP INDEX
69 String index_name;
70
71 // For ADD CONSTRAINT
72 ASTPtr constraint_decl = nullptr;
73
74 // For ADD/DROP CONSTRAINT
75 String constraint_name;
76
77 /// For MODIFY TTL
78 ASTPtr ttl = nullptr;
79
80 /// indicates that this command should not be applied, for example in case of if_exists=true and column doesn't exist.
81 bool ignore = false;
82
83 /// For ADD and MODIFY
84 CompressionCodecPtr codec = nullptr;
85
86 /// For MODIFY SETTING
87 SettingsChanges settings_changes;
88
89 static std::optional<AlterCommand> parse(const ASTAlterCommand * command);
90
91 void apply(StorageInMemoryMetadata & metadata) const;
92
93 /// Checks that alter query changes data. For MergeTree:
94 /// * column files (data and marks)
95 /// * each part meta (columns.txt)
96 /// in each part on disk (it's not lightweight alter).
97 bool isModifyingData() const;
98
99 /// Checks that only settings changed by alter
100 bool isSettingsAlter() const;
101
102 /// Checks that only comment changed by alter
103 bool isCommentAlter() const;
104};
105
106/// Return string representation of AlterCommand::Type
107String alterTypeToString(const AlterCommand::Type type);
108
109class Context;
110
111/// Vector of AlterCommand with several additional functions
112class AlterCommands : public std::vector<AlterCommand>
113{
114private:
115 bool prepared = false;
116public:
117 /// Validate that commands can be applied to metadata.
118 /// Checks that all columns exist and dependecies between them.
119 /// This check is lightweight and base only on metadata.
120 /// More accurate check have to be performed with storage->checkAlterIsPossible.
121 void validate(const StorageInMemoryMetadata & metadata, const Context & context) const;
122
123 /// Prepare alter commands. Set ignore flag to some of them
124 /// and additional commands for dependent columns.
125 void prepare(const StorageInMemoryMetadata & metadata, const Context & context);
126
127 /// Apply all alter command in sequential order to storage metadata.
128 /// Commands have to be prepared before apply.
129 void apply(StorageInMemoryMetadata & metadata) const;
130
131 /// At least one command modify data on disk.
132 bool isModifyingData() const;
133
134 /// At least one command modify settings.
135 bool isSettingsAlter() const;
136
137 /// At least one command modify comments.
138 bool isCommentAlter() const;
139};
140
141}
142