1#include <Common/typeid_cast.h>
2#include <Parsers/ASTSetQuery.h>
3#include <Parsers/ASTFunction.h>
4#include <Parsers/ASTIdentifier.h>
5#include <Parsers/ASTSelectQuery.h>
6#include <Parsers/ASTOrderByElement.h>
7#include <Parsers/ASTTablesInSelectQuery.h>
8
9
10namespace DB
11{
12
13namespace ErrorCodes
14{
15 extern const int LOGICAL_ERROR;
16}
17
18
19ASTPtr ASTSelectQuery::clone() const
20{
21 auto res = std::make_shared<ASTSelectQuery>(*this);
22 res->children.clear();
23 res->positions.clear();
24
25#define CLONE(expr) res->setExpression(expr, getExpression(expr, true))
26
27 /** NOTE Members must clone exactly in the same order,
28 * in which they were inserted into `children` in ParserSelectQuery.
29 * This is important because of the children's names the identifier (getTreeHash) is compiled,
30 * which can be used for column identifiers in the case of subqueries in the IN statement.
31 * For distributed query processing, in case one of the servers is localhost and the other one is not,
32 * localhost query is executed within the process and is cloned,
33 * and the request is sent to the remote server in text form via TCP.
34 * And if the cloning order does not match the parsing order,
35 * then different servers will get different identifiers.
36 */
37 CLONE(Expression::WITH);
38 CLONE(Expression::SELECT);
39 CLONE(Expression::TABLES);
40 CLONE(Expression::PREWHERE);
41 CLONE(Expression::WHERE);
42 CLONE(Expression::GROUP_BY);
43 CLONE(Expression::HAVING);
44 CLONE(Expression::ORDER_BY);
45 CLONE(Expression::LIMIT_BY_OFFSET);
46 CLONE(Expression::LIMIT_BY_LENGTH);
47 CLONE(Expression::LIMIT_BY);
48 CLONE(Expression::LIMIT_OFFSET);
49 CLONE(Expression::LIMIT_LENGTH);
50 CLONE(Expression::SETTINGS);
51
52#undef CLONE
53
54 return res;
55}
56
57
58void ASTSelectQuery::formatImpl(const FormatSettings & s, FormatState & state, FormatStateStacked frame) const
59{
60 frame.current_select = this;
61 frame.need_parens = false;
62 std::string indent_str = s.one_line ? "" : std::string(4 * frame.indent, ' ');
63
64 if (with())
65 {
66 s.ostr << (s.hilite ? hilite_keyword : "") << indent_str << "WITH " << (s.hilite ? hilite_none : "");
67 s.one_line
68 ? with()->formatImpl(s, state, frame)
69 : with()->as<ASTExpressionList &>().formatImplMultiline(s, state, frame);
70 s.ostr << s.nl_or_ws;
71 }
72
73 s.ostr << (s.hilite ? hilite_keyword : "") << indent_str << "SELECT " << (distinct ? "DISTINCT " : "") << (s.hilite ? hilite_none : "");
74
75 s.one_line
76 ? select()->formatImpl(s, state, frame)
77 : select()->as<ASTExpressionList &>().formatImplMultiline(s, state, frame);
78
79 if (tables())
80 {
81 s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "FROM " << (s.hilite ? hilite_none : "");
82 tables()->formatImpl(s, state, frame);
83 }
84
85 if (prewhere())
86 {
87 s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "PREWHERE " << (s.hilite ? hilite_none : "");
88 prewhere()->formatImpl(s, state, frame);
89 }
90
91 if (where())
92 {
93 s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "WHERE " << (s.hilite ? hilite_none : "");
94 where()->formatImpl(s, state, frame);
95 }
96
97 if (groupBy())
98 {
99 s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "GROUP BY " << (s.hilite ? hilite_none : "");
100 s.one_line
101 ? groupBy()->formatImpl(s, state, frame)
102 : groupBy()->as<ASTExpressionList &>().formatImplMultiline(s, state, frame);
103 }
104
105 if (group_by_with_rollup)
106 s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << (s.one_line ? "" : " ") << "WITH ROLLUP" << (s.hilite ? hilite_none : "");
107
108 if (group_by_with_cube)
109 s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << (s.one_line ? "" : " ") << "WITH CUBE" << (s.hilite ? hilite_none : "");
110
111 if (group_by_with_totals)
112 s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << (s.one_line ? "" : " ") << "WITH TOTALS" << (s.hilite ? hilite_none : "");
113
114 if (having())
115 {
116 s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "HAVING " << (s.hilite ? hilite_none : "");
117 having()->formatImpl(s, state, frame);
118 }
119
120 if (orderBy())
121 {
122 s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "ORDER BY " << (s.hilite ? hilite_none : "");
123 s.one_line
124 ? orderBy()->formatImpl(s, state, frame)
125 : orderBy()->as<ASTExpressionList &>().formatImplMultiline(s, state, frame);
126 }
127
128 if (limitByLength())
129 {
130 s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "LIMIT " << (s.hilite ? hilite_none : "");
131 if (limitByOffset())
132 {
133 limitByOffset()->formatImpl(s, state, frame);
134 s.ostr << ", ";
135 }
136 limitByLength()->formatImpl(s, state, frame);
137 s.ostr << (s.hilite ? hilite_keyword : "") << " BY " << (s.hilite ? hilite_none : "");
138 s.one_line
139 ? limitBy()->formatImpl(s, state, frame)
140 : limitBy()->as<ASTExpressionList &>().formatImplMultiline(s, state, frame);
141 }
142
143 if (limitLength())
144 {
145 s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "LIMIT " << (s.hilite ? hilite_none : "");
146 if (limitOffset())
147 {
148 limitOffset()->formatImpl(s, state, frame);
149 s.ostr << ", ";
150 }
151 limitLength()->formatImpl(s, state, frame);
152 if (limit_with_ties)
153 s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << " WITH TIES" << (s.hilite ? hilite_none : "");
154 }
155
156 if (settings())
157 {
158 s.ostr << (s.hilite ? hilite_keyword : "") << s.nl_or_ws << indent_str << "SETTINGS " << (s.hilite ? hilite_none : "");
159 settings()->formatImpl(s, state, frame);
160 }
161}
162
163
164/// Compatibility functions. TODO Remove.
165
166
167static const ASTTableExpression * getFirstTableExpression(const ASTSelectQuery & select)
168{
169 if (!select.tables())
170 return {};
171
172 const auto & tables_in_select_query = select.tables()->as<ASTTablesInSelectQuery &>();
173 if (tables_in_select_query.children.empty())
174 return {};
175
176 const auto & tables_element = tables_in_select_query.children[0]->as<ASTTablesInSelectQueryElement &>();
177 if (!tables_element.table_expression)
178 return {};
179
180 return tables_element.table_expression->as<ASTTableExpression>();
181}
182
183static ASTTableExpression * getFirstTableExpression(ASTSelectQuery & select)
184{
185 if (!select.tables())
186 return {};
187
188 auto & tables_in_select_query = select.tables()->as<ASTTablesInSelectQuery &>();
189 if (tables_in_select_query.children.empty())
190 return {};
191
192 auto & tables_element = tables_in_select_query.children[0]->as<ASTTablesInSelectQueryElement &>();
193 if (!tables_element.table_expression)
194 return {};
195
196 return tables_element.table_expression->as<ASTTableExpression>();
197}
198
199static const ASTArrayJoin * getFirstArrayJoin(const ASTSelectQuery & select)
200{
201 if (!select.tables())
202 return {};
203
204 const auto & tables_in_select_query = select.tables()->as<ASTTablesInSelectQuery &>();
205 if (tables_in_select_query.children.empty())
206 return {};
207
208 const ASTArrayJoin * array_join = nullptr;
209 for (const auto & child : tables_in_select_query.children)
210 {
211 const auto & tables_element = child->as<ASTTablesInSelectQueryElement &>();
212 if (tables_element.array_join)
213 {
214 if (!array_join)
215 array_join = tables_element.array_join->as<ASTArrayJoin>();
216 else
217 throw Exception("Support for more than one ARRAY JOIN in query is not implemented", ErrorCodes::NOT_IMPLEMENTED);
218 }
219 }
220
221 return array_join;
222}
223
224static const ASTTablesInSelectQueryElement * getFirstTableJoin(const ASTSelectQuery & select)
225{
226 if (!select.tables())
227 return nullptr;
228
229 const auto & tables_in_select_query = select.tables()->as<ASTTablesInSelectQuery &>();
230 if (tables_in_select_query.children.empty())
231 return nullptr;
232
233 const ASTTablesInSelectQueryElement * joined_table = nullptr;
234 for (const auto & child : tables_in_select_query.children)
235 {
236 const auto & tables_element = child->as<ASTTablesInSelectQueryElement &>();
237 if (tables_element.table_join)
238 {
239 if (!joined_table)
240 joined_table = &tables_element;
241 else
242 throw Exception("Multiple JOIN does not support the query.", ErrorCodes::NOT_IMPLEMENTED);
243 }
244 }
245
246 return joined_table;
247}
248
249
250ASTPtr ASTSelectQuery::sample_size() const
251{
252 const ASTTableExpression * table_expression = getFirstTableExpression(*this);
253 if (!table_expression)
254 return {};
255
256 return table_expression->sample_size;
257}
258
259
260ASTPtr ASTSelectQuery::sample_offset() const
261{
262 const ASTTableExpression * table_expression = getFirstTableExpression(*this);
263 if (!table_expression)
264 return {};
265
266 return table_expression->sample_offset;
267}
268
269
270bool ASTSelectQuery::final() const
271{
272 const ASTTableExpression * table_expression = getFirstTableExpression(*this);
273 if (!table_expression)
274 return {};
275
276 return table_expression->final;
277}
278
279bool ASTSelectQuery::withFill() const
280{
281 if (!orderBy())
282 return false;
283
284 for (const auto & order_expression_element : orderBy()->children)
285 if (order_expression_element->as<ASTOrderByElement &>().with_fill)
286 return true;
287
288 return false;
289}
290
291
292ASTPtr ASTSelectQuery::array_join_expression_list(bool & is_left) const
293{
294 const ASTArrayJoin * array_join = getFirstArrayJoin(*this);
295 if (!array_join)
296 return {};
297
298 is_left = (array_join->kind == ASTArrayJoin::Kind::Left);
299 return array_join->expression_list;
300}
301
302
303ASTPtr ASTSelectQuery::array_join_expression_list() const
304{
305 bool is_left;
306 return array_join_expression_list(is_left);
307}
308
309
310const ASTTablesInSelectQueryElement * ASTSelectQuery::join() const
311{
312 return getFirstTableJoin(*this);
313}
314
315static String getTableExpressionAlias(const ASTTableExpression * table_expression)
316{
317 if (table_expression->subquery)
318 return table_expression->subquery->tryGetAlias();
319 else if (table_expression->table_function)
320 return table_expression->table_function->tryGetAlias();
321 else if (table_expression->database_and_table_name)
322 return table_expression->database_and_table_name->tryGetAlias();
323
324 return String();
325}
326
327void ASTSelectQuery::replaceDatabaseAndTable(const String & database_name, const String & table_name)
328{
329 ASTTableExpression * table_expression = getFirstTableExpression(*this);
330
331 if (!table_expression)
332 {
333 setExpression(Expression::TABLES, std::make_shared<ASTTablesInSelectQuery>());
334 auto element = std::make_shared<ASTTablesInSelectQueryElement>();
335 auto table_expr = std::make_shared<ASTTableExpression>();
336 element->table_expression = table_expr;
337 element->children.emplace_back(table_expr);
338 tables()->children.emplace_back(element);
339 table_expression = table_expr.get();
340 }
341
342 String table_alias = getTableExpressionAlias(table_expression);
343 table_expression->database_and_table_name = createTableIdentifier(database_name, table_name);
344
345 if (!table_alias.empty())
346 table_expression->database_and_table_name->setAlias(table_alias);
347}
348
349
350void ASTSelectQuery::addTableFunction(ASTPtr & table_function_ptr)
351{
352 ASTTableExpression * table_expression = getFirstTableExpression(*this);
353
354 if (!table_expression)
355 {
356 setExpression(Expression::TABLES, std::make_shared<ASTTablesInSelectQuery>());
357 auto element = std::make_shared<ASTTablesInSelectQueryElement>();
358 auto table_expr = std::make_shared<ASTTableExpression>();
359 element->table_expression = table_expr;
360 element->children.emplace_back(table_expr);
361 tables()->children.emplace_back(element);
362 table_expression = table_expr.get();
363 }
364
365 String table_alias = getTableExpressionAlias(table_expression);
366 /// Maybe need to modify the alias, so we should clone new table_function node
367 table_expression->table_function = table_function_ptr->clone();
368 table_expression->database_and_table_name = nullptr;
369
370 if (table_alias.empty())
371 table_expression->table_function->setAlias(table_alias);
372}
373
374void ASTSelectQuery::setExpression(Expression expr, ASTPtr && ast)
375{
376 if (ast)
377 {
378 auto it = positions.find(expr);
379 if (it == positions.end())
380 {
381 positions[expr] = children.size();
382 children.emplace_back(ast);
383 }
384 else
385 children[it->second] = ast;
386 }
387 else if (positions.count(expr))
388 {
389 size_t pos = positions[expr];
390 children.erase(children.begin() + pos);
391 positions.erase(expr);
392 for (auto & pr : positions)
393 if (pr.second > pos)
394 --pr.second;
395 }
396}
397
398ASTPtr & ASTSelectQuery::getExpression(Expression expr)
399{
400 if (!positions.count(expr))
401 throw Exception("Get expression before set", ErrorCodes::LOGICAL_ERROR);
402 return children[positions[expr]];
403}
404
405}
406