| 245 | |
| 246 | |
| 247 | ASTPtr tryParseQuery( |
| 248 | IParser & parser, |
| 249 | const char * & _out_query_end, /* also query begin as input parameter */ |
| 250 | const char * all_queries_end, |
| 251 | std::string & out_error_message, |
| 252 | bool hilite, |
| 253 | const std::string & query_description, |
| 254 | bool allow_multi_statements, |
| 255 | size_t max_query_size, |
| 256 | size_t max_parser_depth) |
| 257 | { |
| 258 | const char * query_begin = _out_query_end; |
| 259 | Tokens tokens(query_begin, all_queries_end, max_query_size); |
| 260 | tokens.setContext(parser.getContext()); |
| 261 | IParser::Pos token_iterator(tokens, max_parser_depth); |
| 262 | |
| 263 | if (token_iterator->isEnd() |
| 264 | || token_iterator->type == TokenType::Semicolon) |
| 265 | { |
| 266 | out_error_message = "Empty query"; |
| 267 | // Token iterator skips over comments, so we'll get this error for queries |
| 268 | // like this: |
| 269 | // " |
| 270 | // -- just a comment |
| 271 | // ; |
| 272 | //" |
| 273 | // Advance the position, so that we can use this parser for stream parsing |
| 274 | // even in presence of such queries. |
| 275 | _out_query_end = token_iterator->begin; |
| 276 | return nullptr; |
| 277 | } |
| 278 | |
| 279 | Expected expected; |
| 280 | ASTPtr res; |
| 281 | const bool parse_res = parser.parse(token_iterator, res, expected); |
| 282 | const auto last_token = token_iterator.max(); |
| 283 | _out_query_end = last_token.end; |
| 284 | |
| 285 | ASTInsertQuery * insert = nullptr; |
| 286 | if (parse_res) |
| 287 | insert = res->as<ASTInsertQuery>(); |
| 288 | |
| 289 | // If parsed query ends at data for insertion. Data for insertion could be |
| 290 | // in any format and not necessary be lexical correct, so we can't perform |
| 291 | // most of the checks. |
| 292 | if (insert && insert->data) |
| 293 | { |
| 294 | return res; |
| 295 | } |
| 296 | |
| 297 | // More granular checks for queries other than INSERT w/inline data. |
| 298 | /// Lexical error |
| 299 | if (last_token.isError()) |
| 300 | { |
| 301 | out_error_message = getLexicalErrorMessage(query_begin, all_queries_end, |
| 302 | last_token, hilite, query_description); |
| 303 | return nullptr; |
| 304 | } |
no test coverage detected