1#include <memory>
2#include <Parsers/ASTSelectQuery.h>
3#include <Parsers/IParserBase.h>
4#include <Parsers/CommonParsers.h>
5#include <Parsers/ExpressionElementParsers.h>
6#include <Parsers/ExpressionListParsers.h>
7#include <Parsers/ParserSetQuery.h>
8#include <Parsers/ParserSampleRatio.h>
9#include <Parsers/ParserSelectQuery.h>
10#include <Parsers/ParserTablesInSelectQuery.h>
11
12
13namespace DB
14{
15
16namespace ErrorCodes
17{
18 extern const int SYNTAX_ERROR;
19 extern const int TOP_AND_LIMIT_TOGETHER;
20 extern const int WITH_TIES_WITHOUT_ORDER_BY;
21 extern const int LIMIT_BY_WITH_TIES_IS_NOT_SUPPORTED;
22}
23
24
25bool ParserSelectQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
26{
27 auto select_query = std::make_shared<ASTSelectQuery>();
28 node = select_query;
29
30 ParserKeyword s_select("SELECT");
31 ParserKeyword s_distinct("DISTINCT");
32 ParserKeyword s_from("FROM");
33 ParserKeyword s_prewhere("PREWHERE");
34 ParserKeyword s_where("WHERE");
35 ParserKeyword s_group_by("GROUP BY");
36 ParserKeyword s_with("WITH");
37 ParserKeyword s_totals("TOTALS");
38 ParserKeyword s_having("HAVING");
39 ParserKeyword s_order_by("ORDER BY");
40 ParserKeyword s_limit("LIMIT");
41 ParserKeyword s_settings("SETTINGS");
42 ParserKeyword s_by("BY");
43 ParserKeyword s_rollup("ROLLUP");
44 ParserKeyword s_cube("CUBE");
45 ParserKeyword s_top("TOP");
46 ParserKeyword s_with_ties("WITH TIES");
47 ParserKeyword s_offset("OFFSET");
48
49 ParserNotEmptyExpressionList exp_list(false);
50 ParserNotEmptyExpressionList exp_list_for_with_clause(false);
51 ParserNotEmptyExpressionList exp_list_for_select_clause(true); /// Allows aliases without AS keyword.
52 ParserExpressionWithOptionalAlias exp_elem(false);
53 ParserOrderByExpressionList order_list;
54
55 ParserToken open_bracket(TokenType::OpeningRoundBracket);
56 ParserToken close_bracket(TokenType::ClosingRoundBracket);
57
58 ASTPtr with_expression_list;
59 ASTPtr select_expression_list;
60 ASTPtr tables;
61 ASTPtr prewhere_expression;
62 ASTPtr where_expression;
63 ASTPtr group_expression_list;
64 ASTPtr having_expression;
65 ASTPtr order_expression_list;
66 ASTPtr limit_by_length;
67 ASTPtr limit_by_offset;
68 ASTPtr limit_by_expression_list;
69 ASTPtr limit_offset;
70 ASTPtr limit_length;
71 ASTPtr top_length;
72 ASTPtr settings;
73
74 /// WITH expr list
75 {
76 if (s_with.ignore(pos, expected))
77 {
78 if (!exp_list_for_with_clause.parse(pos, with_expression_list, expected))
79 return false;
80 }
81 }
82
83 /// SELECT [DISTINCT] [TOP N [WITH TIES]] expr list
84 {
85 if (!s_select.ignore(pos, expected))
86 return false;
87
88 if (s_distinct.ignore(pos, expected))
89 select_query->distinct = true;
90
91 if (s_top.ignore(pos, expected))
92 {
93 ParserNumber num;
94
95 if (open_bracket.ignore(pos, expected))
96 {
97 if (!num.parse(pos, top_length, expected))
98 return false;
99 if (!close_bracket.ignore(pos, expected))
100 return false;
101 }
102 else
103 {
104 if (!num.parse(pos, top_length, expected))
105 return false;
106 }
107
108 if (s_with_ties.ignore(pos, expected))
109 select_query->limit_with_ties = true;
110 }
111
112 if (!exp_list_for_select_clause.parse(pos, select_expression_list, expected))
113 return false;
114 }
115
116 /// FROM database.table or FROM table or FROM (subquery) or FROM tableFunction(...)
117 if (s_from.ignore(pos, expected))
118 {
119 if (!ParserTablesInSelectQuery().parse(pos, tables, expected))
120 return false;
121 }
122
123 /// PREWHERE expr
124 if (s_prewhere.ignore(pos, expected))
125 {
126 if (!exp_elem.parse(pos, prewhere_expression, expected))
127 return false;
128 }
129
130 /// WHERE expr
131 if (s_where.ignore(pos, expected))
132 {
133 if (!exp_elem.parse(pos, where_expression, expected))
134 return false;
135 }
136
137 /// GROUP BY expr list
138 if (s_group_by.ignore(pos, expected))
139 {
140 if (s_rollup.ignore(pos, expected))
141 select_query->group_by_with_rollup = true;
142 else if (s_cube.ignore(pos, expected))
143 select_query->group_by_with_cube = true;
144
145 if ((select_query->group_by_with_rollup || select_query->group_by_with_cube) && !open_bracket.ignore(pos, expected))
146 return false;
147
148 if (!exp_list.parse(pos, group_expression_list, expected))
149 return false;
150
151 if ((select_query->group_by_with_rollup || select_query->group_by_with_cube) && !close_bracket.ignore(pos, expected))
152 return false;
153 }
154
155 /// WITH ROLLUP, CUBE or TOTALS
156 if (s_with.ignore(pos, expected))
157 {
158 if (s_rollup.ignore(pos, expected))
159 select_query->group_by_with_rollup = true;
160 else if (s_cube.ignore(pos, expected))
161 select_query->group_by_with_cube = true;
162 else if (s_totals.ignore(pos, expected))
163 select_query->group_by_with_totals = true;
164 else
165 return false;
166 }
167
168 /// WITH TOTALS
169 if (s_with.ignore(pos, expected))
170 {
171 if (select_query->group_by_with_totals || !s_totals.ignore(pos, expected))
172 return false;
173
174 select_query->group_by_with_totals = true;
175 }
176
177 /// HAVING expr
178 if (s_having.ignore(pos, expected))
179 {
180 if (!exp_elem.parse(pos, having_expression, expected))
181 return false;
182 }
183
184 /// ORDER BY expr ASC|DESC COLLATE 'locale' list
185 if (s_order_by.ignore(pos, expected))
186 {
187 if (!order_list.parse(pos, order_expression_list, expected))
188 return false;
189 }
190
191 /// This is needed for TOP expression, because it can also use WITH TIES.
192 bool limit_with_ties_occured = false;
193
194 /// LIMIT length | LIMIT offset, length | LIMIT count BY expr-list | LIMIT offset, length BY expr-list
195 if (s_limit.ignore(pos, expected))
196 {
197 ParserToken s_comma(TokenType::Comma);
198
199 if (!exp_elem.parse(pos, limit_length, expected))
200 return false;
201
202 if (s_comma.ignore(pos, expected))
203 {
204 limit_offset = limit_length;
205 if (!exp_elem.parse(pos, limit_length, expected))
206 return false;
207
208 if (s_with_ties.ignore(pos, expected))
209 {
210 limit_with_ties_occured = true;
211 select_query->limit_with_ties = true;
212 }
213 }
214 else if (s_offset.ignore(pos, expected))
215 {
216 if (!exp_elem.parse(pos, limit_offset, expected))
217 return false;
218 }
219 else if (s_with_ties.ignore(pos, expected))
220 {
221 limit_with_ties_occured = true;
222 select_query->limit_with_ties = true;
223 }
224
225 if (s_by.ignore(pos, expected))
226 {
227 /// WITH TIES was used alongside LIMIT BY
228 /// But there are other kind of queries like LIMIT n BY smth LIMIT m WITH TIES which are allowed.
229 /// So we have to ignore WITH TIES exactly in LIMIT BY state.
230 if (limit_with_ties_occured)
231 throw Exception("Can not use WITH TIES alongside LIMIT BY", ErrorCodes::LIMIT_BY_WITH_TIES_IS_NOT_SUPPORTED);
232
233 limit_by_length = limit_length;
234 limit_by_offset = limit_offset;
235 limit_length = nullptr;
236 limit_offset = nullptr;
237
238 if (!exp_list.parse(pos, limit_by_expression_list, expected))
239 return false;
240 }
241
242 if (top_length && limit_length)
243 throw Exception("Can not use TOP and LIMIT together", ErrorCodes::TOP_AND_LIMIT_TOGETHER);
244 }
245
246 /// Because TOP n in totally equals LIMIT n
247 if (top_length)
248 limit_length = top_length;
249
250 /// LIMIT length [WITH TIES] | LIMIT offset, length [WITH TIES]
251 if (s_limit.ignore(pos, expected))
252 {
253 if (!limit_by_length || limit_length)
254 return false;
255
256 ParserToken s_comma(TokenType::Comma);
257
258 if (!exp_elem.parse(pos, limit_length, expected))
259 return false;
260
261 if (s_comma.ignore(pos, expected))
262 {
263 limit_offset = limit_length;
264 if (!exp_elem.parse(pos, limit_length, expected))
265 return false;
266 }
267 else if (s_offset.ignore(pos, expected))
268 {
269 if (!exp_elem.parse(pos, limit_offset, expected))
270 return false;
271 }
272
273 if (s_with_ties.ignore(pos, expected))
274 select_query->limit_with_ties = true;
275 }
276
277 /// WITH TIES was used without ORDER BY
278 if (!order_expression_list && select_query->limit_with_ties)
279 throw Exception("Can not use WITH TIES without ORDER BY", ErrorCodes::WITH_TIES_WITHOUT_ORDER_BY);
280
281 /// SETTINGS key1 = value1, key2 = value2, ...
282 if (s_settings.ignore(pos, expected))
283 {
284 ParserSetQuery parser_settings(true);
285
286 if (!parser_settings.parse(pos, settings, expected))
287 return false;
288 }
289
290 select_query->setExpression(ASTSelectQuery::Expression::WITH, std::move(with_expression_list));
291 select_query->setExpression(ASTSelectQuery::Expression::SELECT, std::move(select_expression_list));
292 select_query->setExpression(ASTSelectQuery::Expression::TABLES, std::move(tables));
293 select_query->setExpression(ASTSelectQuery::Expression::PREWHERE, std::move(prewhere_expression));
294 select_query->setExpression(ASTSelectQuery::Expression::WHERE, std::move(where_expression));
295 select_query->setExpression(ASTSelectQuery::Expression::GROUP_BY, std::move(group_expression_list));
296 select_query->setExpression(ASTSelectQuery::Expression::HAVING, std::move(having_expression));
297 select_query->setExpression(ASTSelectQuery::Expression::ORDER_BY, std::move(order_expression_list));
298 select_query->setExpression(ASTSelectQuery::Expression::LIMIT_BY_OFFSET, std::move(limit_by_offset));
299 select_query->setExpression(ASTSelectQuery::Expression::LIMIT_BY_LENGTH, std::move(limit_by_length));
300 select_query->setExpression(ASTSelectQuery::Expression::LIMIT_BY, std::move(limit_by_expression_list));
301 select_query->setExpression(ASTSelectQuery::Expression::LIMIT_OFFSET, std::move(limit_offset));
302 select_query->setExpression(ASTSelectQuery::Expression::LIMIT_LENGTH, std::move(limit_length));
303 select_query->setExpression(ASTSelectQuery::Expression::SETTINGS, std::move(settings));
304 return true;
305}
306
307}
308