| 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 | |