diff --git a/src/Functions/keyvaluepair/impl/CHKeyValuePairExtractor.h b/src/Functions/keyvaluepair/impl/CHKeyValuePairExtractor.h index 0a1bc4fe5102..aa9e421c901a 100644 --- a/src/Functions/keyvaluepair/impl/CHKeyValuePairExtractor.h +++ b/src/Functions/keyvaluepair/impl/CHKeyValuePairExtractor.h @@ -7,6 +7,7 @@ #include #include +// TODO: debug stuff, remove it before merging #include #include @@ -16,9 +17,6 @@ namespace DB template class CHKeyValuePairExtractor : public KeyValuePairExtractor { - using Key = typename StateHandler::KeyType; - using Value = typename StateHandler::ValueType; - using State = typename DB::extractKV::StateHandler::State; using NextState = DB::extractKV::StateHandler::NextState; @@ -37,8 +35,8 @@ class CHKeyValuePairExtractor : public KeyValuePairExtractor // std::cerr << "CHKeyValuePairExtractor::extract: \"" << data << "\"" << std::endl; auto state = State::WAITING_KEY; - Key key; - Value value; + extractKV::StringWriter key(*keys); + extractKV::StringWriter value(*values); uint64_t row_offset = 0; const auto & config = state_handler.extractor_configuration; @@ -59,7 +57,7 @@ class CHKeyValuePairExtractor : public KeyValuePairExtractor << fancyQuote(data) << std::endl; - next_state = processState(data, state, key, value, keys, values, row_offset); + next_state = processState(data, state, key, value, row_offset); std::cerr << "CHKeyValuePairExtractor::extract 2, new_state: " << magic_enum::enum_name(next_state.state) @@ -83,18 +81,21 @@ class CHKeyValuePairExtractor : public KeyValuePairExtractor break; } + // TODO (vnemkov): consider removing, we should reach FLUSH_PAIR state from state machine. // if break occured earlier, consume previously generated pair - if (state == State::FLUSH_PAIR || !(key.empty() && value.empty())) - flushPair(data, key, value, keys, values, row_offset); + if (state == State::FLUSH_PAIR || !(key.isEmpty() && value.isEmpty())) + flushPair(data, key, value, row_offset); + + keys->validate(); + values->validate(); return row_offset; } private: - NextState processState(std::string_view file, State state, Key & key, - Value & value, ColumnString::MutablePtr & keys, - ColumnString::MutablePtr & values, uint64_t & row_offset) + NextState processState(std::string_view file, State state, extractKV::StringWriter & key, + extractKV::StringWriter & value, uint64_t & row_offset) { switch (state) { @@ -103,13 +104,13 @@ class CHKeyValuePairExtractor : public KeyValuePairExtractor case State::READING_KEY: { auto result = state_handler.readKey(file, key); - std::cerr << "CHKeyValuePairExtractor::processState key: " << fancyQuote(key) << std::endl; + std::cerr << "CHKeyValuePairExtractor::processState key: " << fancyQuote(key.uncommittedChunk()) << std::endl; return result; } case State::READING_QUOTED_KEY: { auto result = state_handler.readQuotedKey(file, key); - std::cerr << "CHKeyValuePairExtractor::processState key: " << fancyQuote(key) << std::endl; + std::cerr << "CHKeyValuePairExtractor::processState key: " << fancyQuote(key.uncommittedChunk()) << std::endl; return result; } case State::READING_KV_DELIMITER: @@ -121,33 +122,29 @@ class CHKeyValuePairExtractor : public KeyValuePairExtractor case State::READING_VALUE: { auto result = state_handler.readValue(file, value); - std::cerr << "CHKeyValuePairExtractor::processState value: " << fancyQuote(value) << std::endl; + std::cerr << "CHKeyValuePairExtractor::processState value: " << fancyQuote(value.uncommittedChunk()) << std::endl; return result; } case State::READING_QUOTED_VALUE: { auto result = state_handler.readQuotedValue(file, value); - std::cerr << "CHKeyValuePairExtractor::processState value: " << fancyQuote(value) << std::endl; + std::cerr << "CHKeyValuePairExtractor::processState value: " << fancyQuote(value.uncommittedChunk()) << std::endl; return result; } case State::FLUSH_PAIR: - return flushPair(file, key, value, keys, values, row_offset); + return flushPair(file, key, value, row_offset); case State::END: return {0, state}; } } - NextState flushPair(const std::string_view & file, Key & key, - Value & value, ColumnString::MutablePtr & keys, - ColumnString::MutablePtr & values, uint64_t & row_offset) + NextState flushPair(const std::string_view & file, extractKV::StringWriter & key, + extractKV::StringWriter & value, uint64_t & row_offset) { - std::cerr << "CHKeyValuePairExtractor::flushPair key: " << fancyQuote(key) << ", value: " << fancyQuote(value) << std::endl; - keys->insertData(key.data(), key.size()); - values->insertData(value.data(), value.size()); - - key = {}; - value = {}; + std::cerr << "CHKeyValuePairExtractor::flushPair key: " << fancyQuote(key.uncommittedChunk()) << ", value: " << fancyQuote(value.uncommittedChunk()) << std::endl; + key.commit(); + value.commit(); ++row_offset; std::cerr << "CHKeyValuePairExtractor::flushPair total pairs: " << row_offset << std::endl; diff --git a/src/Functions/keyvaluepair/impl/InlineEscapingStateHandler.cpp b/src/Functions/keyvaluepair/impl/InlineEscapingStateHandler.cpp index 198d09d28967..06daf780378d 100644 --- a/src/Functions/keyvaluepair/impl/InlineEscapingStateHandler.cpp +++ b/src/Functions/keyvaluepair/impl/InlineEscapingStateHandler.cpp @@ -7,12 +7,15 @@ namespace { -size_t consumeWithEscapeSequence(std::string_view file, size_t start_pos, size_t character_pos, std::string & output) +size_t consumeWithEscapeSequence(std::string_view file, size_t start_pos, size_t character_pos, DB::extractKV::StringWriter & output) { - output.insert(output.end(), file.begin() + start_pos, file.begin() + character_pos); + output.append(file.begin() + start_pos, file.begin() + character_pos); + std::string tmp_out; DB::ReadBufferFromMemory buf(file.begin() + character_pos, file.size() - character_pos); - DB::parseComplexEscapeSequence(output, buf); + + DB::parseComplexEscapeSequence(tmp_out, buf); + output.append(tmp_out); return buf.getPosition(); } @@ -62,11 +65,11 @@ NextState InlineEscapingStateHandler::waitKey(std::string_view file) const * If I find a key value delimiter and that is empty, I do not need to copy? hm,m hm hm * */ -NextState InlineEscapingStateHandler::readKey(std::string_view file, KeyType & key) const +NextState InlineEscapingStateHandler::readKey(std::string_view file, StringWriter & key) const { const auto & [key_value_delimiter, _, pair_delimiters] = extractor_configuration; - key.clear(); + key.reset(); size_t pos = 0; while (const auto * p = find_first_symbols_or_null({file.begin() + pos, file.end()}, read_needles)) @@ -83,9 +86,10 @@ NextState InlineEscapingStateHandler::readKey(std::string_view file, KeyType & k return {next_pos, State::WAITING_KEY}; } } - else if (*p == key_value_delimiter) + else + if (*p == key_value_delimiter) { - key.insert(key.end(), file.begin() + pos, file.begin() + character_position); + key.append(file.begin() + pos, file.begin() + character_position); return {next_pos, State::WAITING_VALUE}; } @@ -102,11 +106,11 @@ NextState InlineEscapingStateHandler::readKey(std::string_view file, KeyType & k return {file.size(), State::END}; } -NextState InlineEscapingStateHandler::readQuotedKey(std::string_view file, KeyType & key) const +NextState InlineEscapingStateHandler::readQuotedKey(std::string_view file, StringWriter & key) const { const auto quoting_character = extractor_configuration.quoting_character; - key.clear(); + key.reset(); size_t pos = 0; while (const auto * p = find_first_symbols_or_null({file.begin() + pos, file.end()}, read_quoted_needles)) @@ -126,9 +130,9 @@ NextState InlineEscapingStateHandler::readQuotedKey(std::string_view file, KeyTy } else if (*p == quoting_character) { - key.insert(key.end(), file.begin() + pos, file.begin() + character_position); + key.append(file.begin() + pos, file.begin() + character_position); - if (key.empty()) + if (key.isEmpty()) { return {next_pos, State::WAITING_KEY}; } @@ -172,11 +176,11 @@ NextState InlineEscapingStateHandler::waitValue(std::string_view file) const return {pos, State::READING_VALUE}; } -NextState InlineEscapingStateHandler::readValue(std::string_view file, ValueType & value) const +NextState InlineEscapingStateHandler::readValue(std::string_view file, StringWriter & value) const { const auto & [key_value_delimiter, _, pair_delimiters] = extractor_configuration; - value.clear(); + value.reset(); size_t pos = 0; while (const auto * p = find_first_symbols_or_null({file.begin() + pos, file.end()}, read_needles)) @@ -192,11 +196,12 @@ NextState InlineEscapingStateHandler::readValue(std::string_view file, ValueType { // It is agreed that value with an invalid escape seqence in it // is considered malformed and shoudn't be included in result. - value.clear(); + value.reset(); return {next_pos, State::WAITING_KEY}; } } - else if (*p == key_value_delimiter) + else + if (*p == key_value_delimiter) { // reached new key return {next_pos, State::WAITING_KEY}; @@ -204,7 +209,7 @@ NextState InlineEscapingStateHandler::readValue(std::string_view file, ValueType else if (std::find(pair_delimiters.begin(), pair_delimiters.end(), *p) != pair_delimiters.end()) { // reached next pair - value.insert(value.end(), file.begin() + pos, file.begin() + character_position); + value.append(file.begin() + pos, file.begin() + character_position); return {next_pos, State::FLUSH_PAIR}; } @@ -213,17 +218,17 @@ NextState InlineEscapingStateHandler::readValue(std::string_view file, ValueType } // Reached end of input, consume rest of the file as value and make sure KV pair is produced. - value.insert(value.end(), file.begin() + pos, file.end()); + value.append(file.begin() + pos, file.end()); return {file.size(), State::FLUSH_PAIR}; } -NextState InlineEscapingStateHandler::readQuotedValue(std::string_view file, ValueType & value) const +NextState InlineEscapingStateHandler::readQuotedValue(std::string_view file, StringWriter & value) const { const auto quoting_character = extractor_configuration.quoting_character; size_t pos = 0; - value.clear(); + value.reset(); while (const auto * p = find_first_symbols_or_null({file.begin() + pos, file.end()}, read_quoted_needles)) { @@ -239,9 +244,10 @@ NextState InlineEscapingStateHandler::readQuotedValue(std::string_view file, Val return {next_pos, State::WAITING_KEY}; } } - else if (*p == quoting_character) + else + if (*p == quoting_character) { - value.insert(value.end(), file.begin() + pos, file.begin() + character_position); + value.append(file.begin() + pos, file.begin() + character_position); return {next_pos, State::FLUSH_PAIR}; } diff --git a/src/Functions/keyvaluepair/impl/InlineEscapingStateHandler.h b/src/Functions/keyvaluepair/impl/InlineEscapingStateHandler.h index 120d2f3d95bb..2d532a4938d9 100644 --- a/src/Functions/keyvaluepair/impl/InlineEscapingStateHandler.h +++ b/src/Functions/keyvaluepair/impl/InlineEscapingStateHandler.h @@ -16,18 +16,15 @@ namespace extractKV class InlineEscapingStateHandler : public StateHandler { public: - using KeyType = std::string; - using ValueType = std::string; - explicit InlineEscapingStateHandler(Configuration configuration_); [[nodiscard]] NextState waitKey(std::string_view file) const; - [[nodiscard]] NextState readKey(std::string_view file, KeyType & key) const; - [[nodiscard]] NextState readQuotedKey(std::string_view file, KeyType & key) const; + [[nodiscard]] NextState readKey(std::string_view file, StringWriter & key) const; + [[nodiscard]] NextState readQuotedKey(std::string_view file, StringWriter & key) const; [[nodiscard]] NextState readKeyValueDelimiter(std::string_view file) const; [[nodiscard]] NextState waitValue(std::string_view file) const; - [[nodiscard]] NextState readValue(std::string_view file, ValueType & value) const; - [[nodiscard]] NextState readQuotedValue(std::string_view file, ValueType & value) const; + [[nodiscard]] NextState readValue(std::string_view file, StringWriter & value) const; + [[nodiscard]] NextState readQuotedValue(std::string_view file, StringWriter & value) const; const Configuration extractor_configuration; diff --git a/src/Functions/keyvaluepair/impl/NoEscapingStateHandler.cpp b/src/Functions/keyvaluepair/impl/NoEscapingStateHandler.cpp index 68f18ffca838..e3715bb1bca2 100644 --- a/src/Functions/keyvaluepair/impl/NoEscapingStateHandler.cpp +++ b/src/Functions/keyvaluepair/impl/NoEscapingStateHandler.cpp @@ -3,15 +3,11 @@ #include #include +#include "Functions/keyvaluepair/impl/StateHandler.h" namespace { -std::string_view createElement(std::string_view file, std::size_t begin, std::size_t end) -{ - return std::string_view{file.begin() + begin, file.begin() + end}; -} - using NextState = DB::extractKV::StateHandler::NextState; } @@ -51,11 +47,11 @@ NextState NoEscapingStateHandler::waitKey(std::string_view file) const return {file.size(), State::END}; } -NextState NoEscapingStateHandler::readKey(std::string_view file, KeyType & key) const +NextState NoEscapingStateHandler::readKey(std::string_view file, StringWriter & key) const { const auto & [key_value_delimiter, _, pair_delimiters] = extractor_configuration; - key = {}; + key.reset(); size_t pos = 0; auto start_index = pos; @@ -67,9 +63,9 @@ NextState NoEscapingStateHandler::readKey(std::string_view file, KeyType & key) if (*p == key_value_delimiter) { - key = createElement(file, start_index, character_position); + key.append(file.begin() + start_index, file.begin() + character_position); - if (key.empty()) + if (key.isEmpty()) { return {next_pos, State::WAITING_KEY}; } @@ -88,25 +84,25 @@ NextState NoEscapingStateHandler::readKey(std::string_view file, KeyType & key) return {file.size(), State::END}; } -NextState NoEscapingStateHandler::readQuotedKey(std::string_view file, KeyType & key) const +NextState NoEscapingStateHandler::readQuotedKey(std::string_view file, StringWriter & key) const { const auto quoting_character = extractor_configuration.quoting_character; - key = {}; + key.reset(); size_t pos = 0; auto start_index = pos; while (const auto * p = find_first_symbols_or_null({file.begin() + pos, file.end()}, read_quoted_needles)) { - const size_t character_position = p - file.begin(); - auto next_pos = character_position + 1u; + size_t character_position = p - file.begin(); + size_t next_pos = character_position + 1u; if (*p == quoting_character) { - key = createElement(file, start_index, character_position); + key.append(file.begin() + start_index, file.begin() + character_position); - if (key.empty()) + if (key.isEmpty()) { return {next_pos, State::WAITING_KEY}; } @@ -150,11 +146,11 @@ NextState NoEscapingStateHandler::waitValue(std::string_view file) const return {pos, State::READING_VALUE}; } -NextState NoEscapingStateHandler::readValue(std::string_view file, ValueType & value) const +NextState NoEscapingStateHandler::readValue(std::string_view file, StringWriter & value) const { const auto & [key_value_delimiter, _, pair_delimiters] = extractor_configuration; - value = {}; + value.reset(); size_t pos = 0; auto start_index = pos; @@ -170,7 +166,7 @@ NextState NoEscapingStateHandler::readValue(std::string_view file, ValueType & v else if (std::find(pair_delimiters.begin(), pair_delimiters.end(), *p) != pair_delimiters.end()) { // reached next pair - value = createElement(file, start_index, character_position); + value.append(file.begin() + start_index, file.begin() + character_position); return {next_pos, State::FLUSH_PAIR}; } @@ -180,18 +176,18 @@ NextState NoEscapingStateHandler::readValue(std::string_view file, ValueType & v // TODO: do I really need the below logic? // this allows empty values at the end - value = createElement(file, start_index, file.size()); + value.append(file.begin() + start_index, file.end()); return {file.size(), State::FLUSH_PAIR}; } -NextState NoEscapingStateHandler::readQuotedValue(std::string_view file, ValueType & value) const +NextState NoEscapingStateHandler::readQuotedValue(std::string_view file, StringWriter & value) const { const auto quoting_character = extractor_configuration.quoting_character; size_t pos = 0; auto start_index = pos; - value = {}; + value.reset(); while (const auto * p = find_first_symbols_or_null({file.begin() + pos, file.end()}, read_quoted_needles)) { @@ -200,7 +196,7 @@ NextState NoEscapingStateHandler::readQuotedValue(std::string_view file, ValueTy if (*p == quoting_character) { - value = createElement(file, start_index, character_position); + value.append(file.begin() + start_index, file.begin() + character_position); std::cerr << "NoEscapingStateHandler::readQuoted Going to consume up to: «" << fancyQuote(file.substr(0, next_pos)) << " to " << fancyQuote(file.substr(next_pos)) << std::endl; return {next_pos, State::FLUSH_PAIR}; diff --git a/src/Functions/keyvaluepair/impl/NoEscapingStateHandler.h b/src/Functions/keyvaluepair/impl/NoEscapingStateHandler.h index e547a503530f..fa426939d7e0 100644 --- a/src/Functions/keyvaluepair/impl/NoEscapingStateHandler.h +++ b/src/Functions/keyvaluepair/impl/NoEscapingStateHandler.h @@ -16,18 +16,15 @@ namespace extractKV class NoEscapingStateHandler : public StateHandler { public: - using KeyType = std::string_view; - using ValueType = std::string_view; - explicit NoEscapingStateHandler(Configuration extractor_configuration_); [[nodiscard]] NextState waitKey(std::string_view file) const; - [[nodiscard]] NextState readKey(std::string_view file, KeyType & key) const; - [[nodiscard]] NextState readQuotedKey(std::string_view file, KeyType & key) const; + [[nodiscard]] NextState readKey(std::string_view file, StringWriter & key) const; + [[nodiscard]] NextState readQuotedKey(std::string_view file, StringWriter & key) const; [[nodiscard]] NextState readKeyValueDelimiter(std::string_view file) const; [[nodiscard]] NextState waitValue(std::string_view file) const; - [[nodiscard]] NextState readValue(std::string_view file, ValueType & value) const; - [[nodiscard]] NextState readQuotedValue(std::string_view file, ValueType & value) const; + [[nodiscard]] NextState readValue(std::string_view file, StringWriter & value) const; + [[nodiscard]] NextState readQuotedValue(std::string_view file, StringWriter & value) const; const Configuration extractor_configuration; diff --git a/src/Functions/keyvaluepair/impl/StateHandler.h b/src/Functions/keyvaluepair/impl/StateHandler.h index 362e2d9618ff..6feb1977c736 100644 --- a/src/Functions/keyvaluepair/impl/StateHandler.h +++ b/src/Functions/keyvaluepair/impl/StateHandler.h @@ -1,5 +1,7 @@ #pragma once +#include + #include #include @@ -46,11 +48,75 @@ class StateHandler virtual ~StateHandler() = default; }; + +class StringWriter +{ + ColumnString & col; + ColumnString::Chars & chars; + UInt64 prev_commit_pos = 0; + +public: + StringWriter(ColumnString & col_) + : col(col_), + chars(col.getChars()) + {} + + ~StringWriter() + { + // Make sure that ColumnString invariants are not broken. + if (!isEmpty()) + reset(); + } + + void append(std::string_view new_data) + { + chars.insert(new_data.begin(), new_data.end()); + } + + template + void append(const T * begin, const T * end) + { + chars.insert(begin, end); + } + + void reset() + { + chars.resize_assume_reserved(prev_commit_pos); + } + + bool isEmpty() const + { + return chars.size() == prev_commit_pos; + } + + void commit() + { + if (isEmpty()) + return; + + chars.push_back('\0'); + std::cerr << "Committing on " << &col << " prev_commit_pos: " << prev_commit_pos << " new offset: " << chars.size() << " there will be " << col.getOffsets().size() + 1 << " rows" << std::endl; + col.getOffsets().emplace_back(chars.size()); + prev_commit_pos = chars.size(); + } + + std::string_view uncommittedChunk() const + { + return std::string_view(chars.raw_data() + prev_commit_pos, chars.raw_data() + chars.size()); + } + +// const ColumnString & data() const +// { +// return col; +// } +}; + + } // TODO(vnemkov): Debug stuff, remove before merging -template +template struct CustomQuoted { const char * start_quote = "\""; @@ -59,31 +125,35 @@ struct CustomQuoted const T & value; }; -template -CustomQuoted customQuote(const char * start_quote, const T & value, const char * end_quote = nullptr) +template +CustomQuoted customQuote(const char * start_quote, const T & value, const char * end_quote = nullptr) { assert(start_quote != nullptr); - return CustomQuoted{ + return CustomQuoted{ .start_quote = start_quote, .end_quote = end_quote ? end_quote : start_quote, .value = value }; } -template -CustomQuoted fancyQuote(const T & value) +inline auto fancyQuote(const std::string_view & value) { - return CustomQuoted{ + return CustomQuoted{ .start_quote = "«", .end_quote = "»", .value = value }; } -template -std::ostream & operator<<(std::ostream & ostr, const CustomQuoted & val) +template +std::ostream & operator<<(std::ostream & ostr, const CustomQuoted & val) { + if constexpr (prepend_length) + { + ostr << "(" << val.value.length() << ") "; + } + return ostr << val.start_quote << val.value << val.end_quote; } diff --git a/src/Functions/keyvaluepair/tests/gtest_escaping_key_value_pair_extractor.cpp b/src/Functions/keyvaluepair/tests/gtest_escaping_key_value_pair_extractor.cpp index 91ec1ca74a05..784a259b3dc7 100644 --- a/src/Functions/keyvaluepair/tests/gtest_escaping_key_value_pair_extractor.cpp +++ b/src/Functions/keyvaluepair/tests/gtest_escaping_key_value_pair_extractor.cpp @@ -30,8 +30,8 @@ TEST(extractKVPair_EscapingKeyValuePairExtractor, EscapeSequences) ASSERT_EQ(keys->size(), pairs_count); ASSERT_EQ(keys->size(), values->size()); - ASSERT_EQ(keys->getDataAt(0), "key1"); - ASSERT_EQ(keys->getDataAt(1), "key2"); + ASSERT_EQ(keys->getDataAt(0).toView(), "key1"); + ASSERT_EQ(keys->getDataAt(1).toView(), "key2"); assert_byte_equality(values->getDataAt(0), {0xFF}); assert_byte_equality(values->getDataAt(1), {0xA, 0x9, 0xD}); diff --git a/src/Functions/keyvaluepair/tests/gtest_extractKeyValuePairs.cpp b/src/Functions/keyvaluepair/tests/gtest_extractKeyValuePairs.cpp index b259cf1a2efb..ab06fb6e90fd 100644 --- a/src/Functions/keyvaluepair/tests/gtest_extractKeyValuePairs.cpp +++ b/src/Functions/keyvaluepair/tests/gtest_extractKeyValuePairs.cpp @@ -94,11 +94,11 @@ TEST_P(extractKVPair_KeyValuePairExtractorTest, Match) { EXPECT_EQ(expected_kv.first, keys->getDataAt(i)) << fancyQuote(expected_kv.first) << "\nvs\n" - << fancyQuote(keys->getDataAt(i)); + << fancyQuote(keys->getDataAt(i).toView()); EXPECT_EQ(expected_kv.second, values->getDataAt(i)) << fancyQuote(expected_kv.second) << "\nvs\n" - << fancyQuote(values->getDataAt(i)); + << fancyQuote(values->getDataAt(i).toView()); ++i; } diff --git a/src/Functions/keyvaluepair/tests/gtest_inline_escaping_key_state_handler.cpp b/src/Functions/keyvaluepair/tests/gtest_inline_escaping_key_state_handler.cpp index c812aac99851..3a93079b92c8 100644 --- a/src/Functions/keyvaluepair/tests/gtest_inline_escaping_key_state_handler.cpp +++ b/src/Functions/keyvaluepair/tests/gtest_inline_escaping_key_state_handler.cpp @@ -1,5 +1,6 @@ #include -#include +#include + #include #include @@ -25,8 +26,9 @@ template void test_read(const InlineEscapingStateHandler & handler, std::string_view input, std::string_view expected_element, std::size_t expected_pos, State expected_state) { + auto str = ColumnString::create(); NextState next_state; - std::string element; + StringWriter element(*str); if constexpr (quoted) { @@ -39,7 +41,7 @@ void test_read(const InlineEscapingStateHandler & handler, std::string_view inpu ASSERT_EQ(next_state.position_in_string, expected_pos); ASSERT_EQ(next_state.state, expected_state); - ASSERT_EQ(element, expected_element); + ASSERT_EQ(element.uncommittedChunk(), expected_element); } void test_read(const InlineEscapingStateHandler & handler, std::string_view input, std::string_view expected_element, diff --git a/src/Functions/keyvaluepair/tests/gtest_no_escaping_key_state_handler.cpp b/src/Functions/keyvaluepair/tests/gtest_no_escaping_key_state_handler.cpp index 75cf33713932..b162982e9bba 100644 --- a/src/Functions/keyvaluepair/tests/gtest_no_escaping_key_state_handler.cpp +++ b/src/Functions/keyvaluepair/tests/gtest_no_escaping_key_state_handler.cpp @@ -1,6 +1,8 @@ #include #include +#include + #include namespace @@ -24,7 +26,9 @@ void test_read(const auto & handler, std::string_view input, std::string_view ex std::size_t expected_pos, State expected_state) { NextState next_state; - std::string_view element; + + auto col = ColumnString::create(); + StringWriter element(*col); if constexpr (quoted) { @@ -37,7 +41,7 @@ void test_read(const auto & handler, std::string_view input, std::string_view ex ASSERT_EQ(next_state.position_in_string, expected_pos); ASSERT_EQ(next_state.state, expected_state); - ASSERT_EQ(element, expected_element); + ASSERT_EQ(element.uncommittedChunk(), expected_element); } void test_read(const auto & handler, std::string_view input, std::string_view expected_element,