Merge pull request #18329 from azat/buffer-rollback-fix

Fix NULL dereference in Buffer rollback
This commit is contained in:
alexey-milovidov 2020-12-22 09:30:53 +03:00 committed by GitHub
commit c1bd8d5df5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -386,16 +386,17 @@ static void appendBlock(const Block & from, Block & to)
MemoryTracker::BlockerInThread temporarily_disable_memory_tracker; MemoryTracker::BlockerInThread temporarily_disable_memory_tracker;
MutableColumnPtr last_col;
try try
{ {
for (size_t column_no = 0, columns = to.columns(); column_no < columns; ++column_no) for (size_t column_no = 0, columns = to.columns(); column_no < columns; ++column_no)
{ {
const IColumn & col_from = *from.getByPosition(column_no).column.get(); const IColumn & col_from = *from.getByPosition(column_no).column.get();
MutableColumnPtr col_to = IColumn::mutate(std::move(to.getByPosition(column_no).column)); last_col = IColumn::mutate(std::move(to.getByPosition(column_no).column));
col_to->insertRangeFrom(col_from, 0, rows); last_col->insertRangeFrom(col_from, 0, rows);
to.getByPosition(column_no).column = std::move(col_to); to.getByPosition(column_no).column = std::move(last_col);
} }
} }
catch (...) catch (...)
@ -406,6 +407,16 @@ static void appendBlock(const Block & from, Block & to)
for (size_t column_no = 0, columns = to.columns(); column_no < columns; ++column_no) for (size_t column_no = 0, columns = to.columns(); column_no < columns; ++column_no)
{ {
ColumnPtr & col_to = to.getByPosition(column_no).column; ColumnPtr & col_to = to.getByPosition(column_no).column;
/// If there is no column, then the exception was thrown in the middle of append, in the insertRangeFrom()
if (!col_to)
{
col_to = std::move(last_col);
/// Suppress clang-tidy [bugprone-use-after-move]
last_col = {};
}
/// But if there is still nothing, abort
if (!col_to)
throw Exception("No column to rollback", ErrorCodes::LOGICAL_ERROR);
if (col_to->size() != old_rows) if (col_to->size() != old_rows)
col_to = col_to->cut(0, old_rows); col_to = col_to->cut(0, old_rows);
} }