From b443d65ac2af0551c1c47ec1682968d116807d4c Mon Sep 17 00:00:00 2001 From: haitaoyang Date: Mon, 27 Nov 2023 08:33:04 +0000 Subject: [PATCH] Fix group by pushdown to rle/const decoder --- .../encoding/ob_const_decoder.cpp | 19 +++++++++++++++++++ .../blocksstable/encoding/ob_const_decoder.h | 2 ++ .../blocksstable/encoding/ob_dict_decoder.cpp | 16 ++++++++++------ .../blocksstable/encoding/ob_rle_decoder.cpp | 16 ++++++++++++++++ .../blocksstable/encoding/ob_rle_decoder.h | 2 ++ 5 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/storage/blocksstable/encoding/ob_const_decoder.cpp b/src/storage/blocksstable/encoding/ob_const_decoder.cpp index d6959ba02..70febb3a3 100644 --- a/src/storage/blocksstable/encoding/ob_const_decoder.cpp +++ b/src/storage/blocksstable/encoding/ob_const_decoder.cpp @@ -897,6 +897,8 @@ int ObConstDecoder::read_distinct( ctx.col_header_->length_ - meta_header_->offset_, group_by_cell))) { LOG_WARN("Failed to load dict", K(ret)); + } else if (has_null_execption_value()) { + group_by_cell.add_distinct_null_value(); } return ret; } @@ -919,5 +921,22 @@ int ObConstDecoder::read_reference( return ret; } +bool ObConstDecoder::has_null_execption_value() const +{ + int ret = OB_SUCCESS; + bool has_null = false; + const int64_t dict_count = dict_decoder_.get_dict_header()->count_; + if (meta_header_->const_ref_ == dict_count) { + has_null = true; + } else { + int64_t ref; + for (int64_t pos = 0; !has_null && pos < meta_header_->count_; ++pos) { + ref = reinterpret_cast(meta_header_->payload_)[pos]; + has_null = ref >= dict_count; + } + } + return has_null; +} + } // end namespace blocksstable } // end namespace oceanbase diff --git a/src/storage/blocksstable/encoding/ob_const_decoder.h b/src/storage/blocksstable/encoding/ob_const_decoder.h index 04c1d1c02..a6bfc45db 100644 --- a/src/storage/blocksstable/encoding/ob_const_decoder.h +++ b/src/storage/blocksstable/encoding/ob_const_decoder.h @@ -147,6 +147,8 @@ private: int64_t &null_count, uint32_t *ref_buf = nullptr) const; + bool has_null_execption_value() const; + private: const ObConstMetaHeader *meta_header_; ObDictDecoder dict_decoder_; diff --git a/src/storage/blocksstable/encoding/ob_dict_decoder.cpp b/src/storage/blocksstable/encoding/ob_dict_decoder.cpp index 5391b0e94..24657ea01 100644 --- a/src/storage/blocksstable/encoding/ob_dict_decoder.cpp +++ b/src/storage/blocksstable/encoding/ob_dict_decoder.cpp @@ -1471,7 +1471,16 @@ int ObDictDecoder::read_distinct( const char **cell_datas, storage::ObGroupByCell &group_by_cell) const { - return batch_read_distinct(ctx, cell_datas, ctx.col_header_->length_, group_by_cell); + int ret = OB_SUCCESS; + bool has_null = false; + if (OB_FAIL(batch_read_distinct(ctx, cell_datas, ctx.col_header_->length_, group_by_cell))) { + LOG_WARN("Failed to batch read distinct", K(ret)); + } else if (check_has_null(ctx, ctx.col_header_->length_, has_null)) { + LOG_WARN("Failed to check has null", K(ret)); + } else if (has_null) { + group_by_cell.add_distinct_null_value(); + } + return ret; } int ObDictDecoder::batch_read_distinct( @@ -1485,7 +1494,6 @@ int ObDictDecoder::batch_read_distinct( const char *dict_payload = meta_header_->payload_; const common::ObObjType obj_type = ctx.col_header_->get_store_obj_type(); common::ObDatum *datums = group_by_cell.get_group_by_col_datums_to_fill(); - bool has_null = false; group_by_cell.set_distinct_cnt(count); if (meta_header_->is_fix_length_dict()) { const int64_t dict_data_size = meta_header_->data_size_; @@ -1513,10 +1521,6 @@ int ObDictDecoder::batch_read_distinct( } if (OB_FAIL(batch_load_data_to_datum(obj_type, cell_datas, count, integer_mask_, datums))) { LOG_WARN("Failed to batch load data to datum", K(ret)); - } else if (check_has_null(ctx, meta_length, has_null)) { - LOG_WARN("Failed to check has null", K(ret)); - } else if (has_null) { - group_by_cell.add_distinct_null_value(); } return ret; } diff --git a/src/storage/blocksstable/encoding/ob_rle_decoder.cpp b/src/storage/blocksstable/encoding/ob_rle_decoder.cpp index 5309762a0..a9897ecfc 100644 --- a/src/storage/blocksstable/encoding/ob_rle_decoder.cpp +++ b/src/storage/blocksstable/encoding/ob_rle_decoder.cpp @@ -570,6 +570,8 @@ int ObRLEDecoder::read_distinct( ctx.col_header_->length_ - meta_header_->offset_, group_by_cell))) { LOG_WARN("Failed to load dict", K(ret)); + } else if (has_null_value()) { + group_by_cell.add_distinct_null_value(); } return ret; } @@ -588,5 +590,19 @@ int ObRLEDecoder::read_reference( return ret; } +bool ObRLEDecoder::has_null_value() const +{ + int ret = OB_SUCCESS; + bool has_null = false; + int64_t ref; + const int64_t dict_count = dict_decoder_.get_dict_header()->count_; + const ObIntArrayFuncTable &refs = ObIntArrayFuncTable::instance(meta_header_->ref_byte_); + for (int64_t i = 0; !has_null && i < meta_header_->count_; ++i) { + ref = refs.at_(meta_header_->payload_ + ref_offset_, i); + has_null = ref >= dict_count; + } + return has_null; +} + } // end namespace blocksstable } // end namespace oceanbase diff --git a/src/storage/blocksstable/encoding/ob_rle_decoder.h b/src/storage/blocksstable/encoding/ob_rle_decoder.h index 068083d81..67e2129e5 100644 --- a/src/storage/blocksstable/encoding/ob_rle_decoder.h +++ b/src/storage/blocksstable/encoding/ob_rle_decoder.h @@ -150,6 +150,8 @@ private: const int64_t row_cap, storage::ObGroupByCell &group_by_cell) const override; + bool has_null_value() const; + private: const ObRLEMetaHeader *meta_header_; uint16_t ref_offset_;