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