| 298 | } |
| 299 | |
| 300 | bool ValuesBlockInputFormat::parseExpression(IColumn & column, size_t column_idx) |
| 301 | { |
| 302 | const Block & header = getPort().getHeader(); |
| 303 | const IDataType & type = *header.getByPosition(column_idx).type; |
| 304 | auto settings = context->getSettingsRef(); |
| 305 | |
| 306 | /// We need continuous memory containing the expression to use Lexer |
| 307 | skipToNextRow(0, 1); |
| 308 | buf.makeContinuousMemoryFromCheckpointToPos(); |
| 309 | buf.rollbackToCheckpoint(); |
| 310 | |
| 311 | Expected expected; |
| 312 | Tokens tokens(buf.position(), buf.buffer().end()); |
| 313 | IParser::Pos token_iterator(tokens, settings.max_parser_depth); |
| 314 | ASTPtr ast; |
| 315 | ParserExpression parser(ParserSettings::valueOf(settings)); |
| 316 | |
| 317 | bool parsed = parser.parse(token_iterator, ast, expected); |
| 318 | |
| 319 | /// Consider delimiter after value (',' or ')') as part of expression |
| 320 | if (column_idx + 1 != num_columns) |
| 321 | parsed &= token_iterator->type == TokenType::Comma; |
| 322 | else |
| 323 | parsed &= token_iterator->type == TokenType::ClosingRoundBracket; |
| 324 | |
| 325 | if (!parsed) |
| 326 | throw Exception("Cannot parse expression of type " + type.getName() + " here: " |
| 327 | + String(buf.position(), std::min(SHOW_CHARS_ON_SYNTAX_ERROR, buf.buffer().end() - buf.position())), |
| 328 | ErrorCodes::SYNTAX_ERROR); |
| 329 | ++token_iterator; |
| 330 | |
| 331 | if (parser_type_for_column[column_idx] != ParserType::Streaming && dynamic_cast<const ASTLiteral *>(ast.get())) |
| 332 | { |
| 333 | /// It's possible that streaming parsing has failed on some row (e.g. because of '+' sign before integer), |
| 334 | /// but it still can parse the following rows |
| 335 | /// Check if we can use fast streaming parser instead if using templates |
| 336 | bool rollback_on_exception = false; |
| 337 | bool ok = false; |
| 338 | try |
| 339 | { |
| 340 | const auto & serialization = serializations[column_idx]; |
| 341 | serialization->deserializeTextQuoted(column, buf, format_settings); |
| 342 | rollback_on_exception = true; |
| 343 | skipWhitespaceIfAny(buf); |
| 344 | if (checkDelimiterAfterValue(column_idx)) |
| 345 | ok = true; |
| 346 | } |
| 347 | catch (const Exception & e) |
| 348 | { |
| 349 | bool decimal_overflow = e.code() == ErrorCodes::ARGUMENT_OUT_OF_BOUND; |
| 350 | if (!isParseError(e.code()) || decimal_overflow) |
| 351 | throw; |
| 352 | } |
| 353 | if (ok) |
| 354 | { |
| 355 | parser_type_for_column[column_idx] = ParserType::Streaming; |
| 356 | return true; |
| 357 | } |
no test coverage detected