From 7ac41d7fc195004b4efccbd7891466fe956500e1 Mon Sep 17 00:00:00 2001 From: Michael Kolupaev Date: Thu, 21 Mar 2024 23:25:31 +0000 Subject: [PATCH 1/2] Fix segfault in SquashingTransform --- src/Interpreters/SquashingTransform.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/Interpreters/SquashingTransform.cpp b/src/Interpreters/SquashingTransform.cpp index 4ed0dddc191..da608f5e7ce 100644 --- a/src/Interpreters/SquashingTransform.cpp +++ b/src/Interpreters/SquashingTransform.cpp @@ -89,13 +89,25 @@ void SquashingTransform::append(ReferenceType input_block) assert(blocksHaveEqualStructure(input_block, accumulated_block)); - for (size_t i = 0, size = accumulated_block.columns(); i < size; ++i) + try { - const auto source_column = input_block.getByPosition(i).column; + for (size_t i = 0, size = accumulated_block.columns(); i < size; ++i) + { + const auto source_column = input_block.getByPosition(i).column; - auto mutable_column = IColumn::mutate(std::move(accumulated_block.getByPosition(i).column)); - mutable_column->insertRangeFrom(*source_column, 0, source_column->size()); - accumulated_block.getByPosition(i).column = std::move(mutable_column); + auto mutable_column = IColumn::mutate(std::move(accumulated_block.getByPosition(i).column)); + mutable_column->insertRangeFrom(*source_column, 0, source_column->size()); + accumulated_block.getByPosition(i).column = std::move(mutable_column); + } + } + catch (...) + { + /// add() may be called again even after a previous add() threw an exception. + /// Keep accumulated_block in a valid state. + /// Seems ok to discard accumulated data because we're throwing an exception, which the caller will + /// hopefully interpret to mean "this block and all *previous* blocks are potentially lost". + accumulated_block.clear(); + throw; } } @@ -107,6 +119,9 @@ bool SquashingTransform::isEnoughSize(const Block & block) for (const auto & [column, type, name] : block) { + if (!column) + throw Exception(ErrorCodes::LOGICAL_ERROR, "Invalid column in block."); + if (!rows) rows = column->size(); else if (rows != column->size()) From 84daaa1c7ee8196fa16eb71dc2e7b354c39348d4 Mon Sep 17 00:00:00 2001 From: Michael Kolupaev Date: Fri, 22 Mar 2024 20:00:42 +0000 Subject: [PATCH 2/2] Style --- src/Interpreters/SquashingTransform.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Interpreters/SquashingTransform.cpp b/src/Interpreters/SquashingTransform.cpp index da608f5e7ce..41f024df7a7 100644 --- a/src/Interpreters/SquashingTransform.cpp +++ b/src/Interpreters/SquashingTransform.cpp @@ -6,6 +6,7 @@ namespace DB namespace ErrorCodes { extern const int SIZES_OF_COLUMNS_DOESNT_MATCH; + extern const int LOGICAL_ERROR; } SquashingTransform::SquashingTransform(size_t min_block_size_rows_, size_t min_block_size_bytes_)