From 0ac29fa0ba6cc8f978c28d942632afae3b3ef22b Mon Sep 17 00:00:00 2001 From: obdev Date: Tue, 14 Feb 2023 11:44:41 +0000 Subject: [PATCH] Fix reading invalid 8 bytes column in vectorized query. --- src/share/datum/ob_datum.h | 22 +++++++++++++++++-- .../blocksstable/ob_micro_block_reader.cpp | 2 +- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/share/datum/ob_datum.h b/src/share/datum/ob_datum.h index d926d9560..b95bbaf49 100644 --- a/src/share/datum/ob_datum.h +++ b/src/share/datum/ob_datum.h @@ -192,7 +192,10 @@ public: static uint32_t get_reserved_size(const ObObjDatumMapType type); // From ObObj, the caller is responsible for ensuring %ptr_ has enough memory inline int from_obj(const ObObj &obj, const ObObjDatumMapType map_type); - inline int from_storage_datum(const ObDatum &datum, const ObObjDatumMapType map_type); + inline bool need_copy_for_encoding_column_in_flat_format( + const ObDatum &datum, + const ObObjDatumMapType map_type); + inline int from_storage_datum(const ObDatum &datum, const ObObjDatumMapType map_type, bool need_copy = false); // From ObObj, the caller is responsible for ensuring %ptr_ has enough memory inline int from_obj(const ObObj &obj); inline int64_t checksum(const int64_t current) const; @@ -725,7 +728,14 @@ inline int ObDatum::from_obj(const ObObj &obj, const ObObjDatumMapType map_type) return ret; } -inline int ObDatum::from_storage_datum(const ObDatum &datum, const ObObjDatumMapType map_type) +inline bool ObDatum::need_copy_for_encoding_column_in_flat_format( + const ObDatum &datum, + const ObObjDatumMapType map_type) +{ + return OBJ_DATUM_STRING == map_type && sizeof(uint64_t) == datum.len_; +} + +inline int ObDatum::from_storage_datum(const ObDatum &datum, const ObObjDatumMapType map_type, bool need_copy) { int ret = common::OB_SUCCESS; if (datum.is_ext()) { @@ -733,6 +743,14 @@ inline int ObDatum::from_storage_datum(const ObDatum &datum, const ObObjDatumMap COMMON_LOG(WARN, "Invalid argument for ext storage datum to datum", K(ret), K(datum)); } else if (datum.is_null()) { set_null(); + } else if (need_copy && need_copy_for_encoding_column_in_flat_format(datum, map_type)) { + // 1. When need_copy is true, it means that we project multiple rows at one time. + // 2. Datum buffer will be reset each time in ObDASScanOp::reset_access_datums_ptr, + // so it is safe to deep copy 8 bytes column with flat format micro block into datum buffer. + // 3. We project one row each time in ObRow2ExprsProjector::project, so we will not + // deep copy 8 bytes column with flat format micro block into datum buffer. + memcpy(no_cv(ptr_), datum.ptr_, datum.len_); + pack_ = datum.pack_; } else { switch (map_type) { case OBJ_DATUM_NULL: { datum2datum(datum); break; } diff --git a/src/storage/blocksstable/ob_micro_block_reader.cpp b/src/storage/blocksstable/ob_micro_block_reader.cpp index 576e74183..16580a837 100644 --- a/src/storage/blocksstable/ob_micro_block_reader.cpp +++ b/src/storage/blocksstable/ob_micro_block_reader.cpp @@ -653,7 +653,7 @@ int ObMicroBlockReader::get_rows( LOG_WARN("Fail to transfer datum", K(ret), K(i), K(idx), K(row_idx), K(default_row)); } LOG_TRACE("Transfer nop value", K(ret), K(idx), K(row_idx), K(col_idx), K(default_row)); - } else if (OB_FAIL(datum.from_storage_datum(row_buf.storage_datums_[col_idx], map_types.at(i)))) { + } else if (OB_FAIL(datum.from_storage_datum(row_buf.storage_datums_[col_idx], map_types.at(i), true))) { LOG_WARN("Failed to from storage datum", K(ret), K(idx), K(row_idx), K(col_idx), K(row_buf.storage_datums_[col_idx]), KPC_(header)); }