From 8214f32003f8b5b4699d73ce75f2d8d748bd285b Mon Sep 17 00:00:00 2001 From: Pxl <952130278@qq.com> Date: Tue, 8 Mar 2022 18:56:48 +0800 Subject: [PATCH] [fix] fix core dump on minmax_filter with decimal type (#8381) --- be/src/exprs/minmax_predicate.h | 30 ++++++++++++++++++++--------- be/src/exprs/runtime_filter.cpp | 34 ++++++++++++--------------------- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/be/src/exprs/minmax_predicate.h b/be/src/exprs/minmax_predicate.h index 2c8140dcc4..cad94810c5 100644 --- a/be/src/exprs/minmax_predicate.h +++ b/be/src/exprs/minmax_predicate.h @@ -42,9 +42,20 @@ class MinMaxNumFunc : public MinMaxFuncBase { public: MinMaxNumFunc() = default; ~MinMaxNumFunc() = default; - virtual void insert(const void* data) { - if (data == nullptr) return; - const T val_data = *reinterpret_cast(data); + + void insert(const void* data) override { + if (data == nullptr) { + return; + } + + T val_data; + if constexpr (sizeof(T) >= sizeof(int128_t)) { + // use dereference operator on unalign address maybe lead segmentation fault + memcpy(&val_data, data, sizeof(T)); + } else { + val_data = *reinterpret_cast(data); + } + if (_empty) { _min = val_data; _max = val_data; @@ -58,15 +69,16 @@ public: } } - virtual bool find(void* data) { + bool find(void* data) override { if (data == nullptr) { return false; } + T val_data = *reinterpret_cast(data); return val_data >= _min && val_data <= _max; } - Status merge(MinMaxFuncBase* minmax_func, ObjectPool* pool) { + Status merge(MinMaxFuncBase* minmax_func, ObjectPool* pool) override { if constexpr (std::is_same_v) { MinMaxNumFunc* other_minmax = static_cast*>(minmax_func); @@ -95,13 +107,13 @@ public: return Status::OK(); } - virtual bool is_empty() { return _empty; } + bool is_empty() override { return _empty; } - virtual void* get_max() { return &_max; } + void* get_max() override { return &_max; } - virtual void* get_min() { return &_min; } + void* get_min() override { return &_min; } - virtual Status assign(void* min_data, void* max_data) { + Status assign(void* min_data, void* max_data) override { _min = *(T*)min_data; _max = *(T*)max_data; return Status::OK(); diff --git a/be/src/exprs/runtime_filter.cpp b/be/src/exprs/runtime_filter.cpp index 2ab2e1774a..48cee872cc 100644 --- a/be/src/exprs/runtime_filter.cpp +++ b/be/src/exprs/runtime_filter.cpp @@ -775,44 +775,34 @@ public: return _minmax_func->assign(&min_val, &max_val); } case TYPE_TINYINT: { - int8_t min_val; - int8_t max_val; - min_val = static_cast(minmax_filter->min_val().intval()); - max_val = static_cast(minmax_filter->max_val().intval()); + int8_t min_val = static_cast(minmax_filter->min_val().intval()); + int8_t max_val = static_cast(minmax_filter->max_val().intval()); return _minmax_func->assign(&min_val, &max_val); } case TYPE_SMALLINT: { - int16_t min_val; - int16_t max_val; - min_val = static_cast(minmax_filter->min_val().intval()); - max_val = static_cast(minmax_filter->max_val().intval()); + int16_t min_val = static_cast(minmax_filter->min_val().intval()); + int16_t max_val = static_cast(minmax_filter->max_val().intval()); return _minmax_func->assign(&min_val, &max_val); } case TYPE_INT: { - int32_t min_val; - int32_t max_val; - min_val = minmax_filter->min_val().intval(); - max_val = minmax_filter->max_val().intval(); + int32_t min_val = minmax_filter->min_val().intval(); + int32_t max_val = minmax_filter->max_val().intval(); return _minmax_func->assign(&min_val, &max_val); } case TYPE_BIGINT: { - int64_t min_val; - int64_t max_val; - min_val = minmax_filter->min_val().longval(); - max_val = minmax_filter->max_val().longval(); + int64_t min_val = minmax_filter->min_val().longval(); + int64_t max_val = minmax_filter->max_val().longval(); return _minmax_func->assign(&min_val, &max_val); } case TYPE_LARGEINT: { - int128_t min_val; - int128_t max_val; auto min_string_val = minmax_filter->min_val().stringval(); auto max_string_val = minmax_filter->max_val().stringval(); StringParser::ParseResult result; - min_val = StringParser::string_to_int(min_string_val.c_str(), - min_string_val.length(), &result); + int128_t min_val = StringParser::string_to_int( + min_string_val.c_str(), min_string_val.length(), &result); DCHECK(result == StringParser::PARSE_SUCCESS); - max_val = StringParser::string_to_int(max_string_val.c_str(), - max_string_val.length(), &result); + int128_t max_val = StringParser::string_to_int( + max_string_val.c_str(), max_string_val.length(), &result); DCHECK(result == StringParser::PARSE_SUCCESS); return _minmax_func->assign(&min_val, &max_val); }