static void appendBlock(const Block & from, Block & to) { if (!to) throw Exception("Cannot append to empty block", ErrorCodes::LOGICAL_ERROR); assertBlocksHaveEqualStructure(from, to, "Buffer"); from.checkNumberOfRows(); to.checkNumberOfRows(); size_t rows = from.rows(); size_t bytes = from.bytes(); CurrentMetrics::add(CurrentMetrics::StorageBufferRows, rows); CurrentMetrics::add(CurrentMetrics::StorageBufferBytes, bytes); size_t old_rows = to.rows(); try { for (size_t column_no = 0, columns = to.columns(); column_no < columns; ++column_no) { const IColumn & col_from = *from.getByPosition(column_no).column.get(); MutableColumnPtr col_to = (*std::move(to.getByPosition(column_no).column)).mutate(); col_to->insertRangeFrom(col_from, 0, rows); to.getByPosition(column_no).column = std::move(col_to); } } catch (...) { /// Rollback changes. try { /// Avoid "memory limit exceeded" exceptions during rollback. TemporarilyDisableMemoryTracker temporarily_disable_memory_tracker; for (size_t column_no = 0, columns = to.columns(); column_no < columns; ++column_no) { ColumnPtr & col_to = to.getByPosition(column_no).column; if (col_to->size() != old_rows) col_to = (*std::move(col_to)).mutate()->cut(0, old_rows); } } catch (...) { /// In case when we cannot rollback, do not leave incorrect state in memory. std::terminate(); } throw; } }
void MergingSortedBlockInputStream::init(MutableColumns & merged_columns) { /// Read the first blocks, initialize the queue. if (first) { first = false; for (size_t i = 0; i < source_blocks.size(); ++i) { SharedBlockPtr & shared_block_ptr = source_blocks[i]; if (shared_block_ptr.get()) continue; shared_block_ptr = new detail::SharedBlock(children[i]->read()); const size_t rows = shared_block_ptr->rows(); if (rows == 0) continue; if (expected_block_size < rows) expected_block_size = std::min(rows, max_block_size); cursors[i] = SortCursorImpl(*shared_block_ptr, description, i); shared_block_ptr->all_columns = cursors[i].all_columns; shared_block_ptr->sort_columns = cursors[i].sort_columns; has_collation |= cursors[i].has_collation; } if (has_collation) initQueue(queue_with_collation); else initQueue(queue_without_collation); } /// Let's check that all source blocks have the same structure. for (const SharedBlockPtr & shared_block_ptr : source_blocks) { if (!*shared_block_ptr) continue; assertBlocksHaveEqualStructure(*shared_block_ptr, header, getName()); } merged_columns.resize(num_columns); for (size_t i = 0; i < num_columns; ++i) { merged_columns[i] = header.safeGetByPosition(i).column->cloneEmpty(); merged_columns[i]->reserve(expected_block_size); } }