jacktengg commented on code in PR #28249:
URL: https://github.com/apache/doris/pull/28249#discussion_r1429453047


##########
be/src/vec/data_types/data_type_decimal.h:
##########
@@ -410,73 +412,69 @@ constexpr bool IsDataTypeDecimalOrNumber =
 
 // only for casting between other integral types and decimals
 template <typename FromDataType, typename ToDataType, bool 
multiply_may_overflow,
-          bool narrow_integral>
+          bool narrow_integral, typename RealFrom, typename RealTo>
     requires IsDataTypeDecimal<FromDataType> && IsDataTypeDecimal<ToDataType>
-ToDataType::FieldType convert_decimals(const typename FromDataType::FieldType& 
value,
-                                       UInt32 scale_from, UInt32 scale_to,
-                                       const typename ToDataType::FieldType& 
min_result,
-                                       const typename ToDataType::FieldType& 
max_result) {
+void convert_to_decimals(RealTo* dst, const RealFrom* src, UInt32 scale_from, 
UInt32 scale_to,
+                         const typename ToDataType::FieldType& min_result,
+                         const typename ToDataType::FieldType& max_result, 
size_t size) {
     using FromFieldType = typename FromDataType::FieldType;
     using ToFieldType = typename ToDataType::FieldType;
-    using MaxFieldType =
-            std::conditional_t<(sizeof(FromFieldType) == sizeof(ToFieldType)) 
&&
-                                       (std::is_same_v<ToFieldType, 
Decimal128I> ||
-                                        std::is_same_v<FromFieldType, 
Decimal128I>),
-                               Decimal128I,
-                               std::conditional_t<(sizeof(FromFieldType) > 
sizeof(ToFieldType)),
-                                                  FromFieldType, ToFieldType>>;
+    using MaxFieldType = std::conditional_t<(sizeof(FromFieldType) > 
sizeof(ToFieldType)),
+                                            FromFieldType, ToFieldType>;
 
-    MaxFieldType converted_value;
+    DCHECK_GE(scale_to, scale_from);
     // from integer to decimal
-    if (scale_to > scale_from) {
-        converted_value =
-                DataTypeDecimal<MaxFieldType>::get_scale_multiplier(scale_to - 
scale_from);
+    MaxFieldType multiplier =
+            DataTypeDecimal<MaxFieldType>::get_scale_multiplier(scale_to - 
scale_from);
+    MaxFieldType tmp;
+    for (size_t i = 0; i < size; i++) {
         if constexpr (multiply_may_overflow) {
-            if (common::mul_overflow(static_cast<MaxFieldType>(value).value, 
converted_value.value,
-                                     converted_value.value)) {
+            if (common::mul_overflow(static_cast<MaxFieldType>(src[i]).value, 
multiplier.value,
+                                     tmp.value)) {
                 throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR, 
"Arithmetic overflow");
-            } else {
-                if constexpr (narrow_integral) {
-                    if (UNLIKELY(converted_value.value > max_result.value ||
-                                 converted_value.value < min_result.value)) {
-                        throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
-                                        "Arithmetic overflow");
-                    }
-                }
-            }
-        } else {
-            converted_value *= static_cast<MaxFieldType>(value).value;
-            if constexpr (narrow_integral) {
-                if (UNLIKELY(converted_value.value > max_result.value ||
-                             converted_value.value < min_result.value)) {
-                    throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR, 
"Arithmetic overflow");
-                }
             }
-        }
-    } else {
-        // from decimal to integer
-        converted_value =
-                static_cast<MaxFieldType>(value) /
-                DataTypeDecimal<MaxFieldType>::get_scale_multiplier(scale_from 
- scale_to);
-        if (value >= FromFieldType(0)) {
             if constexpr (narrow_integral) {
-                if (UNLIKELY(converted_value.value > max_result.value)) {
-                    throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR, 
"Arithmetic overflow");
+                if (tmp.value < min_result.value || tmp.value > 
max_result.value) {
+                    throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
+                                    "Arithmetic overflow, convert failed from 
{}, "
+                                    "expected data is [{}, {}]",
+                                    tmp.value, min_result.value, 
max_result.value);
                 }
             }
+            dst[i].value = tmp.value;
         } else {
+            dst[i].value = multiplier.value * 
static_cast<MaxFieldType>(src[i]).value;
             if constexpr (narrow_integral) {
-                if (UNLIKELY(converted_value.value < min_result.value)) {
-                    throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR, 
"Arithmetic overflow");
+                if (dst[i].value < min_result.value || dst[i].value > 
max_result.value) {
+                    throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
+                                    "Arithmetic overflow, convert failed from 
{}, "
+                                    "expected data is [{}, {}]",
+                                    dst[i].value, min_result.value, 
max_result.value);
                 }
             }
         }
     }
+}
+
+// only for casting between other integral types and decimals
+template <typename FromDataType, typename ToDataType, bool 
multiply_may_overflow,
+          bool narrow_integral, typename RealFrom, typename RealTo>
+    requires IsDataTypeDecimal<FromDataType> && IsDataTypeDecimal<ToDataType>
+void convert_from_decimals(RealTo* dst, const RealFrom* src, UInt32 
scale_from, size_t size) {
+    using FromFieldType = typename FromDataType::FieldType;
+    using ToFieldType = typename ToDataType::FieldType;
+    using MaxFieldType = std::conditional_t<(sizeof(FromFieldType) > 
sizeof(ToFieldType)),
+                                            FromFieldType, ToFieldType>;
 
-    return converted_value;
+    // from decimal to integer
+    MaxFieldType multiplier = 
DataTypeDecimal<MaxFieldType>::get_scale_multiplier(scale_from);
+    for (size_t i = 0; i < size; i++) {
+        dst[i] = static_cast<MaxFieldType>(src[i]).value / multiplier.value;

Review Comment:
   need to check overflow, e.g. cast decimal128 to int.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to