1#include <Parsers/ASTAlterQuery.h>
2#include <iomanip>
3#include <Common/quoteString.h>
4
5
6namespace DB
7{
8
9namespace ErrorCodes
10{
11 extern const int UNEXPECTED_AST_STRUCTURE;
12}
13
14ASTPtr 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
63void 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
264ASTPtr 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
272void 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. */
289String ASTAlterQuery::getID(char delim) const
290{
291 return "AlterQuery" + (delim + database) + delim + table;
292}
293
294ASTPtr 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
305void 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