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 | |
13 | namespace DB |
14 | { |
15 | |
16 | namespace 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 | |
25 | bool 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 | |