This is an automated email from the ASF dual-hosted git repository. yiguolei pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push: new 409640ac46 [Bug](decimal) Prevent invalid decimal value (#23677) 409640ac46 is described below commit 409640ac4616ed4aad70ed7ae92c3f4c44010d23 Author: Gabriel <gabrielleeb...@gmail.com> AuthorDate: Thu Aug 31 14:43:10 2023 +0800 [Bug](decimal) Prevent invalid decimal value (#23677) --- be/src/vec/data_types/data_type_decimal.h | 13 ++++++++++++ be/src/vec/sink/vtablet_block_convertor.cpp | 31 +++++++++++++++++++++++++++-- be/src/vec/sink/vtablet_block_convertor.h | 3 +++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/be/src/vec/data_types/data_type_decimal.h b/be/src/vec/data_types/data_type_decimal.h index 275f356ff7..bdd9598836 100644 --- a/be/src/vec/data_types/data_type_decimal.h +++ b/be/src/vec/data_types/data_type_decimal.h @@ -572,4 +572,17 @@ ToDataType::FieldType convert_to_decimal(const typename FromDataType::FieldType& } } +template <typename T> + requires IsDecimalNumber<T> +typename T::NativeType max_decimal_value(UInt32 precision) { + return type_limit<T>::max() / DataTypeDecimal<T>::get_scale_multiplier( + (UInt32)(max_decimal_precision<T>() - precision)); +} + +template <typename T> + requires IsDecimalNumber<T> +typename T::NativeType min_decimal_value(UInt32 precision) { + return type_limit<T>::min() / DataTypeDecimal<T>::get_scale_multiplier( + (UInt32)(max_decimal_precision<T>() - precision)); +} } // namespace doris::vectorized diff --git a/be/src/vec/sink/vtablet_block_convertor.cpp b/be/src/vec/sink/vtablet_block_convertor.cpp index 7c7300b9b3..45105e0cff 100644 --- a/be/src/vec/sink/vtablet_block_convertor.cpp +++ b/be/src/vec/sink/vtablet_block_convertor.cpp @@ -131,6 +131,33 @@ DecimalV2Value OlapTableBlockConvertor::_get_decimalv2_min_or_max(const TypeDesc return value; } +template <typename DecimalType, bool IsMin> +DecimalType OlapTableBlockConvertor::_get_decimalv3_min_or_max(const TypeDescriptor& type) { + std::map<int, typename DecimalType::NativeType>* pmap; + if constexpr (std::is_same_v<DecimalType, vectorized::Decimal32>) { + pmap = IsMin ? &_min_decimal32_val : &_max_decimal32_val; + } else if constexpr (std::is_same_v<DecimalType, vectorized::Decimal64>) { + pmap = IsMin ? &_min_decimal64_val : &_max_decimal64_val; + } else { + pmap = IsMin ? &_min_decimal128_val : &_max_decimal128_val; + } + + // found + auto iter = pmap->find(type.precision); + if (iter != pmap->end()) { + return iter->second; + } + + typename DecimalType::NativeType value; + if constexpr (IsMin) { + value = vectorized::min_decimal_value<DecimalType>(type.precision); + } else { + value = vectorized::max_decimal_value<DecimalType>(type.precision); + } + pmap->emplace(type.precision, value); + return value; +} + Status OlapTableBlockConvertor::_validate_column(RuntimeState* state, const TypeDescriptor& type, bool is_nullable, vectorized::ColumnPtr column, size_t slot_index, bool* stop_processing, @@ -269,8 +296,8 @@ Status OlapTableBlockConvertor::_validate_column(RuntimeState* state, const Type #define CHECK_VALIDATION_FOR_DECIMALV3(DecimalType) \ auto column_decimal = const_cast<vectorized::ColumnDecimal<DecimalType>*>( \ assert_cast<const vectorized::ColumnDecimal<DecimalType>*>(real_column_ptr.get())); \ - const auto& max_decimal = type_limit<DecimalType>::max(); \ - const auto& min_decimal = type_limit<DecimalType>::min(); \ + const auto& max_decimal = _get_decimalv3_min_or_max<DecimalType, false>(type); \ + const auto& min_decimal = _get_decimalv3_min_or_max<DecimalType, true>(type); \ for (size_t j = 0; j < column->size(); ++j) { \ auto row = rows ? (*rows)[j] : j; \ if (row == last_invalid_row) { \ diff --git a/be/src/vec/sink/vtablet_block_convertor.h b/be/src/vec/sink/vtablet_block_convertor.h index 335e876284..bfc7b3b5d9 100644 --- a/be/src/vec/sink/vtablet_block_convertor.h +++ b/be/src/vec/sink/vtablet_block_convertor.h @@ -62,6 +62,9 @@ private: template <bool is_min> DecimalV2Value _get_decimalv2_min_or_max(const TypeDescriptor& type); + template <typename DecimalType, bool IsMin> + DecimalType _get_decimalv3_min_or_max(const TypeDescriptor& type); + Status _validate_column(RuntimeState* state, const TypeDescriptor& type, bool is_nullable, vectorized::ColumnPtr column, size_t slot_index, bool* stop_processing, fmt::memory_buffer& error_prefix, --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org