Repository: duckdb/duckdb
File: src/common/types/data_chunk.cpp (C++)

Code before:
	auto unified_data = make_unsafe_uniq_array<UnifiedVectorFormat>(ColumnCount());
	for (idx_t col_idx = 0; col_idx < ColumnCount(); col_idx++) {
		data[col_idx].ToUnifiedFormat(size(), unified_data[col_idx]);
	}
	return unified_data;
}

void DataChunk::Hash(Vector &result) {
	D_ASSERT(result.GetType().id() == LogicalType::HASH);
	VectorOperations::Hash(data[0], result, size());
	for (idx_t i = 1; i < ColumnCount(); i++) {
		VectorOperations::CombineHash(result, data[i], size());
	}
}

void DataChunk::Hash(vector<idx_t> &column_ids, Vector &result) {
	D_ASSERT(result.GetType().id() == LogicalType::HASH);
	D_ASSERT(!column_ids.empty());

	VectorOperations::Hash(data[column_ids[0]], result, size());
	for (idx_t i = 1; i < column_ids.size(); i++) {
		VectorOperations::CombineHash(result, data[column_ids[i]], size());
	}
}

void DataChunk::Verify(optional_ptr<ClientContext> context, optional_ptr<DBConfig> config) {
#ifdef DEBUG
	D_ASSERT(size() <= capacity);
	// We want to make sure that only one of context or config is set, or no one is set
	D_ASSERT(!(context && config));

	// verify that all vectors in this chunk have the chunk selection vector
	for (idx_t i = 0; i < ColumnCount(); i++) {
		data[i].Verify(size());
	}

	if (!ColumnCount()) {
		// don't try to round-trip dummy data chunks with no data
		// e.g., these exist in queries like 'SELECT distinct(col0, col1) FROM tbl', where we have groups, but no
		// payload so the payload will be such an empty data chunk
		return;
	}

	// verify that we can round-trip chunk serialization
	Allocator allocator;
	MemoryStream mem_stream(allocator);

	// this is the way we can ensure that the `Serialize` and `Deserialize` methods of a `DataChunk` are consistent with
	// each other within the current and previous versions of the code.
	// This is an internal round-trip sanity check performed in memory. It does not write to a
	// persistent database file. Therefore, when a version is not indicated (latest),

Review comment (suggestion):
I think we don't need two optional arguments, we can get away with one. You can get the `DBConfig` from the `DatabaseInstance`, and you can get the `DatabaseInstance` from the `ClientContext`.

I think the only argument should be `optional_ptr<DatabaseInstance>`.

Code after:
unsafe_unique_array<UnifiedVectorFormat> DataChunk::ToUnifiedFormat() {
	auto unified_data = make_unsafe_uniq_array<UnifiedVectorFormat>(ColumnCount());
	for (idx_t col_idx = 0; col_idx < ColumnCount(); col_idx++) {
		data[col_idx].ToUnifiedFormat(size(), unified_data[col_idx]);
	}
	return unified_data;
}

void DataChunk::Hash(Vector &result) {
	D_ASSERT(result.GetType().id() == LogicalType::HASH);
	VectorOperations::Hash(data[0], result, size());
	for (idx_t i = 1; i < ColumnCount(); i++) {
		VectorOperations::CombineHash(result, data[i], size());
	}
}

void DataChunk::Hash(vector<idx_t> &column_ids, Vector &result) {
	D_ASSERT(result.GetType().id() == LogicalType::HASH);
	D_ASSERT(!column_ids.empty());

	VectorOperations::Hash(data[column_ids[0]], result, size());
	for (idx_t i = 1; i < column_ids.size(); i++) {
		VectorOperations::CombineHash(result, data[column_ids[i]], size());
	}
}

void DataChunk::Verify(optional_ptr<DatabaseInstance> database_instance) {
#ifdef DEBUG
	D_ASSERT(size() <= capacity);
	// verify that all vectors in this chunk have the chunk selection vector
	for (idx_t i = 0; i < ColumnCount(); i++) {
		data[i].Verify(size());
	}

	if (!ColumnCount()) {
		// don't try to round-trip dummy data chunks with no data
		// e.g., these exist in queries like 'SELECT distinct(col0, col1) FROM tbl', where we have groups, but no
		// payload so the payload will be such an empty data chunk
		return;
	}

	// verify that we can round-trip chunk serialization
	Allocator allocator;
	MemoryStream mem_stream(allocator);

	// this is the way we can ensure that the `Serialize` and `Deserialize` methods of a `DataChunk` are consistent with
	// each other within the current and previous versions of the code.
	// This is an internal round-trip sanity check performed in memory. It does not write to a
	// persistent database file. Therefore, when a version is not indicated (latest),
	// it should always use the full set of capabilities currently supported by the engine to ensure that all
	// valid in-memory states can be verified.