From 196e3572508e44e6bd24ac4f5a3d44aff4acaab7 Mon Sep 17 00:00:00 2001 From: Alexander Tokmakov Date: Thu, 5 Sep 2019 16:55:51 +0300 Subject: [PATCH] revert parsing expression near the end of buffer --- .../Formats/Impl/ValuesBlockInputFormat.cpp | 44 ++++++------------- 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/dbms/src/Processors/Formats/Impl/ValuesBlockInputFormat.cpp b/dbms/src/Processors/Formats/Impl/ValuesBlockInputFormat.cpp index 55227d8e19a..e482aa3b276 100644 --- a/dbms/src/Processors/Formats/Impl/ValuesBlockInputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/ValuesBlockInputFormat.cpp @@ -86,11 +86,6 @@ Chunk ValuesBlockInputFormat::generate() throw; } } - if (!buf.eof()) - { - assertChar(';', buf); - skipWhitespaceIfAny(buf); - } /// Evaluate expressions, which were parsed using templates, if any for (size_t i = 0; i < columns.size(); ++i) @@ -196,34 +191,23 @@ ValuesBlockInputFormat::parseExpression(IColumn & column, size_t column_idx, boo const IDataType & type = *header.getByPosition(column_idx).type; Expected expected; - auto tokens = std::make_unique(buf.position(), buf.buffer().end()); - IParser::Pos token_iterator(*tokens); + /// TODO use FileSegmentationEngineValues from #6553 to find end of expression and get continuous memory containing expression + Tokens tokens(buf.position(), buf.buffer().end()); + IParser::Pos token_iterator(tokens); ASTPtr ast; - bool near_the_end_of_buffer = true; - bool can_peek = true; - while (near_the_end_of_buffer) + bool parsed = parser.parse(token_iterator, ast, expected); + if (parsed) { - bool parsed = parser.parse(token_iterator, ast, expected); buf.position() = const_cast(token_iterator->begin); - parsed &= checkDelimiterAfterValue(column_idx); - - near_the_end_of_buffer = buf.available() < 256 && can_peek; - if (near_the_end_of_buffer) - { - /// Rare case: possibly only some prefix of expression was parsed. Peek more data and try again - can_peek = buf.peekNext(); - buf.rollbackToCheckpoint(); - tokens = std::make_unique(buf.position(), buf.buffer().end()); - token_iterator = IParser::Pos{*tokens}; - } - else if (!parsed) - { - buf.rollbackToCheckpoint(); - throw Exception("Cannot parse expression of type " + type.getName() + " here: " - + String(buf.position(), std::min(SHOW_CHARS_ON_SYNTAX_ERROR, buf.buffer().end() - buf.position())), - ErrorCodes::SYNTAX_ERROR); - } + parsed = checkDelimiterAfterValue(column_idx); + } + if (!parsed) + { + buf.rollbackToCheckpoint(); + throw Exception("Cannot parse expression of type " + type.getName() + " here: " + + String(buf.position(), std::min(SHOW_CHARS_ON_SYNTAX_ERROR, buf.buffer().end() - buf.position())), + ErrorCodes::SYNTAX_ERROR); } if (format_settings.values.deduce_templates_of_expressions && deduce_template) @@ -233,7 +217,7 @@ ValuesBlockInputFormat::parseExpression(IColumn & column, size_t column_idx, boo ErrorCodes::LOGICAL_ERROR); try { - templates[column_idx] = ConstantExpressionTemplate(header.getByPosition(column_idx).type, TokenIterator(*tokens), token_iterator, ast, *context); + templates[column_idx] = ConstantExpressionTemplate(header.getByPosition(column_idx).type, TokenIterator(tokens), token_iterator, ast, *context); buf.rollbackToCheckpoint(); templates[column_idx].value().parseExpression(buf, format_settings); assertDelimiterAfterValue(column_idx);