diff --git a/src/DataTypes/Serializations/SerializationString.cpp b/src/DataTypes/Serializations/SerializationString.cpp index ac5d4e3e1289..351523e08447 100644 --- a/src/DataTypes/Serializations/SerializationString.cpp +++ b/src/DataTypes/Serializations/SerializationString.cpp @@ -149,6 +149,7 @@ void SerializationString::serializeBinaryBulk(const IColumn & column, WriteBuffe template static NO_INLINE void deserializeBinarySSE2(ColumnString::Chars & data, ColumnString::Offsets & offsets, ReadBuffer & istr, size_t limit) +try { size_t offset = data.size(); /// Avoiding calling resize in a loop improves the performance. @@ -171,8 +172,6 @@ static NO_INLINE void deserializeBinarySSE2(ColumnString::Chars & data, ColumnSt max_string_size); offset += size + 1; - offsets.push_back(offset); - if (unlikely(offset > data.size())) data.resize_exact(roundUpToPowerOfTwoOrZero(std::max(offset, data.size() * 2))); @@ -205,10 +204,18 @@ static NO_INLINE void deserializeBinarySSE2(ColumnString::Chars & data, ColumnSt } data[offset - 1] = 0; + + offsets.push_back(offset); } data.resize_exact(offset); } +catch (...) +{ + /// We are doing resize_exact() of bigger values than we have, let's make sure that it will be correct (even in case of exceptions) + data.resize_exact(offsets.back()); + throw; +} void SerializationString::deserializeBinaryBulk(IColumn & column, ReadBuffer & istr, size_t limit, double avg_value_size_hint) const diff --git a/src/Interpreters/tests/gtest_filecache.cpp b/src/Interpreters/tests/gtest_filecache.cpp index 36acc319f4eb..a8ef43557edb 100644 --- a/src/Interpreters/tests/gtest_filecache.cpp +++ b/src/Interpreters/tests/gtest_filecache.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -286,7 +287,11 @@ void increasePriority(const HolderPtr & holder, size_t pos) class FileCacheTest : public ::testing::Test { public: - FileCacheTest() { + FileCacheTest() + { + /// Reset current_thread to avoid conflicts of ThreadStatus with MainThreadStatus + current_thread = nullptr; + /// Context has to be created before calling cache.initialize(); /// Otherwise the tests which run before FileCacheTest.get are failed /// It is logical to call destroyContext() at destructor. @@ -295,6 +300,12 @@ class FileCacheTest : public ::testing::Test getContext(); } + ~FileCacheTest() override + { + /// Reset current_thread back + current_thread = MainThreadStatus::get(); + } + static void setupLogs(const std::string & level) { Poco::AutoPtr channel(new Poco::ConsoleChannel(std::cerr));