Repository: duckdb/duckdb
File: src/storage/table/update_segment.cpp (C++)

Code before:
		}
		auto pin = entry.Pin();
		idx_t start_in_vector = vector_idx == start_vector ? start_row - start_vector * STANDARD_VECTOR_SIZE : 0;
		idx_t end_in_vector =
		    vector_idx == end_vector ? end_row - end_vector * STANDARD_VECTOR_SIZE : STANDARD_VECTOR_SIZE;
		D_ASSERT(start_in_vector < end_in_vector);
		D_ASSERT(end_in_vector > 0 && end_in_vector <= STANDARD_VECTOR_SIZE);
		idx_t result_offset = ((vector_idx * STANDARD_VECTOR_SIZE) + start_in_vector) - start_row;
		fetch_committed_range(UpdateInfo::Get(pin), start_in_vector, end_in_vector, result_offset, result);
	}
}

//===--------------------------------------------------------------------===//
// Fetch Row
//===--------------------------------------------------------------------===//
static void FetchRowValidity(transaction_t start_time, transaction_t transaction_id, UpdateInfo &info, idx_t row_idx,
                             Vector &result, idx_t result_idx) {
	auto &result_mask = FlatVector::Validity(result);
	UpdateInfo::UpdatesForTransaction(info, start_time, transaction_id, [&](UpdateInfo &current) {
		auto info_data = current.GetData<bool>();
		auto tuples = current.GetTuples();
		idx_t left = 0;
		idx_t right = current.N - 1;
		while (left <= right) {
			idx_t mid = left + (right - left) / 2;
			if (tuples[mid] == row_idx) {
				result_mask.Set(result_idx, info_data[mid]);
				return;
			} else if (tuples[mid] < row_idx) {
				left = mid + 1;
			} else {
				right = mid - 1;
			}
		}
	});
}

template <class T>
static void TemplatedFetchRow(transaction_t start_time, transaction_t transaction_id, UpdateInfo &info, idx_t row_idx,
                              Vector &result, idx_t result_idx) {
	auto result_data = FlatVector::GetData<T>(result);
	UpdateInfo::UpdatesForTransaction(info, start_time, transaction_id, [&](UpdateInfo &current) {
		auto info_data = current.GetData<T>();
		auto tuples = current.GetTuples();
		// FIXME: we could do a binary search in here
		for (idx_t i = 0; i < current.N; i++) {
			if (tuples[i] == row_idx) {
				result_data[result_idx] = info_data[i];
				break;
			} else if (tuples[i] > row_idx) {
				break;

Review comment (bug):
I'm not familiar with the transaction code, but this seems like it could underflow. Maybe `N` cannot be 0, but it's better to be safe than sorry

Code after:
		}
		auto pin = entry.Pin();
		idx_t start_in_vector = vector_idx == start_vector ? start_row - start_vector * STANDARD_VECTOR_SIZE : 0;
		idx_t end_in_vector =
		    vector_idx == end_vector ? end_row - end_vector * STANDARD_VECTOR_SIZE : STANDARD_VECTOR_SIZE;
		D_ASSERT(start_in_vector < end_in_vector);
		D_ASSERT(end_in_vector > 0 && end_in_vector <= STANDARD_VECTOR_SIZE);
		idx_t result_offset = ((vector_idx * STANDARD_VECTOR_SIZE) + start_in_vector) - start_row;
		fetch_committed_range(UpdateInfo::Get(pin), start_in_vector, end_in_vector, result_offset, result);
	}
}

//===--------------------------------------------------------------------===//
// Fetch Row
//===--------------------------------------------------------------------===//
static void FetchRowValidity(transaction_t start_time, transaction_t transaction_id, UpdateInfo &info, idx_t row_idx,
                             Vector &result, idx_t result_idx) {
	auto &result_mask = FlatVector::Validity(result);
	UpdateInfo::UpdatesForTransaction(info, start_time, transaction_id, [&](UpdateInfo &current) {
		auto info_data = current.GetData<bool>();
		auto tuples = current.GetTuples();
		if (current.N == 0) {
			return;
		}
		idx_t left = 0;
		idx_t right = current.N - 1;
		while (left <= right) {
			idx_t mid = left + (right - left) / 2;
			if (tuples[mid] == row_idx) {
				result_mask.Set(result_idx, info_data[mid]);
				return;
			} else if (tuples[mid] < row_idx) {
				left = mid + 1;
			} else {
				right = mid - 1;
			}
		}
	});
}

template <class T>
static void TemplatedFetchRow(transaction_t start_time, transaction_t transaction_id, UpdateInfo &info, idx_t row_idx,
                              Vector &result, idx_t result_idx) {
	auto result_data = FlatVector::GetData<T>(result);
	UpdateInfo::UpdatesForTransaction(info, start_time, transaction_id, [&](UpdateInfo &current) {
		auto info_data = current.GetData<T>();
		auto tuples = current.GetTuples();
		// FIXME: we could do a binary search in here
		for (idx_t i = 0; i < current.N; i++) {
			if (tuples[i] == row_idx) {
				result_data[result_idx] = info_data[i];