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

Reply via email to