This is an automated email from the ASF dual-hosted git repository.

panxiaolei 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 d6514618b2e [Improvement](decimal) reduce overhead on disable check 
decimal overflow (#28249)
d6514618b2e is described below

commit d6514618b2e85b77432a696e9bbe8b36b69845e9
Author: Pxl <[email protected]>
AuthorDate: Tue Dec 19 10:12:30 2023 +0800

    [Improvement](decimal) reduce overhead on disable check decimal overflow 
(#28249)
    
    reduce overhead on disable check decimal overflow
---
 be/src/vec/data_types/data_type_decimal.h          | 366 ++++++++++-----------
 be/src/vec/data_types/number_traits.h              |  12 +-
 be/src/vec/functions/function_binary_arithmetic.h  |  17 +-
 be/src/vec/functions/function_cast.h               | 121 ++-----
 be/src/vec/functions/function_math_log.h           |  92 ++++++
 be/src/vec/functions/function_math_unary.h         | 128 +------
 .../functions/function_math_unary_to_null_type.h   | 148 ---------
 be/src/vec/functions/math.cpp                      |  43 +--
 .../utils/arrow_column_to_doris_column_test.cpp    |  35 --
 .../java/org/apache/doris/qe/SessionVariable.java  |   2 +-
 .../decimalv3/test_decimalv3_cast2.groovy          |  12 +-
 .../suites/mv_p0/ssb/q_4_1_r1/q_4_1_r1.groovy      |   2 +-
 12 files changed, 370 insertions(+), 608 deletions(-)

diff --git a/be/src/vec/data_types/data_type_decimal.h 
b/be/src/vec/data_types/data_type_decimal.h
index fb89c68ec61..7bb78265738 100644
--- a/be/src/vec/data_types/data_type_decimal.h
+++ b/be/src/vec/data_types/data_type_decimal.h
@@ -21,10 +21,12 @@
 #pragma once
 #include <fmt/format.h>
 #include <gen_cpp/Types_types.h>
+#include <glog/logging.h>
 #include <stddef.h>
 #include <stdint.h>
 
 #include <algorithm>
+#include <cassert>
 #include <cmath>
 #include <limits>
 #include <memory>
@@ -410,73 +412,83 @@ 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 {
-            if constexpr (narrow_integral) {
-                if (UNLIKELY(converted_value.value < min_result.value)) {
-                    throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR, 
"Arithmetic overflow");
-                }
+            dst[i].value = multiplier.value * 
static_cast<MaxFieldType>(src[i]).value;
+        }
+    }
+
+    if constexpr (!multiply_may_overflow && narrow_integral) {
+        for (size_t i = 0; i < size; i++) {
+            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);
             }
         }
     }
+}
 
-    return converted_value;
+// only for casting between other integral types and decimals
+template <typename FromDataType, typename ToDataType, bool narrow_integral, 
typename RealFrom,
+          typename RealTo>
+    requires IsDataTypeDecimal<FromDataType> && IsDataTypeDecimal<ToDataType>
+void convert_from_decimals(RealTo* dst, const RealFrom* src, UInt32 scale_from,
+                           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)),
+                                            FromFieldType, ToFieldType>;
+
+    // from decimal to integer
+    MaxFieldType multiplier = 
DataTypeDecimal<MaxFieldType>::get_scale_multiplier(scale_from);
+    for (size_t i = 0; i < size; i++) {
+        auto tmp = static_cast<MaxFieldType>(src[i]).value / multiplier.value;
+        if constexpr (narrow_integral) {
+            if (tmp < min_result.value || tmp > max_result.value) {
+                throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
+                                "Arithmetic overflow, convert failed from {}, "
+                                "expected data is [{}, {}]",
+                                tmp, min_result.value, max_result.value);
+            }
+        }
+        dst[i] = tmp;
+    }
 }
 
-template <typename FromDataType, typename ToDataType>
+template <typename FromDataType, typename ToDataType, bool 
multiply_may_overflow,
+          bool narrow_integral>
 void convert_decimal_cols(
         const typename ColumnDecimal<
                 typename FromDataType::FieldType>::Container::value_type* 
__restrict vec_from,
@@ -495,174 +507,162 @@ void convert_decimal_cols(
     using MaxNativeType = typename MaxFieldType::NativeType;
 
     auto max_result = 
DataTypeDecimal<ToFieldType>::get_max_digits_number(precision_to);
-    bool narrow_integral = (precision_to - scale_to) < (precision_from - 
scale_from);
     if (scale_to > scale_from) {
         const MaxNativeType multiplier =
                 DataTypeDecimal<MaxFieldType>::get_scale_multiplier(scale_to - 
scale_from);
         MaxNativeType res;
-        auto from_max_digits = NumberTraits::max_ascii_len<typename 
FromFieldType::NativeType>();
-        auto to_max_digits = NumberTraits::max_ascii_len<typename 
ToFieldType::NativeType>();
-        bool multiply_may_overflow = (from_max_digits + scale_to - scale_from) 
> to_max_digits;
-        std::visit(
-                [&](auto multiply_may_overflow, auto narrow_integral) {
-                    for (size_t i = 0; i < sz; i++) {
-                        if constexpr (multiply_may_overflow) {
-                            if 
(common::mul_overflow(static_cast<MaxNativeType>(vec_from[i].value),
-                                                     multiplier, res)) {
-                                throw 
Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
-                                                "Arithmetic overflow");
-                            } else {
-                                if (UNLIKELY(res > max_result.value || res < 
-max_result.value)) {
-                                    throw 
Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
-                                                    "Arithmetic overflow, 
convert failed from {}, "
-                                                    "expected data is [{}, 
{}]",
-                                                    res, -max_result.value, 
max_result.value);
-                                } else {
-                                    vec_to[i] = ToFieldType(res);
-                                }
-                            }
-                        } else {
-                            res = vec_from[i].value * multiplier;
-                            if constexpr (narrow_integral) {
-                                if (UNLIKELY(res > max_result.value || res < 
-max_result.value)) {
-                                    throw 
Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
-                                                    "Arithmetic overflow, 
convert failed from {}, "
-                                                    "expected data is [{}, 
{}]",
-                                                    res, -max_result.value, 
max_result.value);
-                                }
-                            }
-                            vec_to[i] = ToFieldType(res);
-                        }
+        for (size_t i = 0; i < sz; i++) {
+            if constexpr (multiply_may_overflow) {
+                if 
(common::mul_overflow(static_cast<MaxNativeType>(vec_from[i].value), multiplier,
+                                         res)) {
+                    throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR, 
"Arithmetic overflow");
+                } else {
+                    if (UNLIKELY(res > max_result.value || res < 
-max_result.value)) {
+                        throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
+                                        "Arithmetic overflow, convert failed 
from {}, "
+                                        "expected data is [{}, {}]",
+                                        res, -max_result.value, 
max_result.value);
+                    } else {
+                        vec_to[i] = ToFieldType(res);
                     }
-                },
-                make_bool_variant(multiply_may_overflow), 
make_bool_variant(narrow_integral));
-    } else if (scale_to == scale_from) {
-        std::visit(
-                [&](auto narrow_integral) {
-                    for (size_t i = 0; i < sz; i++) {
-                        if constexpr (narrow_integral) {
-                            if (UNLIKELY(vec_from[i].value > max_result.value 
||
-                                         vec_from[i].value < 
-max_result.value)) {
-                                throw 
Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
-                                                "Arithmetic overflow, convert 
failed from {}, "
-                                                "expected data is [{}, {}]",
-                                                vec_from[i].value, 
-max_result.value,
-                                                max_result.value);
-                            }
-                        }
-                        vec_to[i] = ToFieldType(vec_from[i].value);
+                }
+            } else {
+                res = vec_from[i].value * multiplier;
+                if constexpr (narrow_integral) {
+                    if (UNLIKELY(res > max_result.value || res < 
-max_result.value)) {
+                        throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
+                                        "Arithmetic overflow, convert failed 
from {}, "
+                                        "expected data is [{}, {}]",
+                                        res, -max_result.value, 
max_result.value);
                     }
-                },
-                make_bool_variant(narrow_integral));
+                }
+                vec_to[i] = ToFieldType(res);
+            }
+        }
+    } else if (scale_to == scale_from) {
+        for (size_t i = 0; i < sz; i++) {
+            if constexpr (narrow_integral) {
+                if (UNLIKELY(vec_from[i].value > max_result.value ||
+                             vec_from[i].value < -max_result.value)) {
+                    throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
+                                    "Arithmetic overflow, convert failed from 
{}, "
+                                    "expected data is [{}, {}]",
+                                    vec_from[i].value, -max_result.value, 
max_result.value);
+                }
+            }
+            vec_to[i] = ToFieldType(vec_from[i].value);
+        }
     } else {
         MaxNativeType multiplier =
                 DataTypeDecimal<MaxFieldType>::get_scale_multiplier(scale_from 
- scale_to);
         MaxNativeType res;
-        std::visit(
-                [&](auto narrow_integral) {
-                    for (size_t i = 0; i < sz; i++) {
-                        if (vec_from[i] >= FromFieldType(0)) {
-                            if constexpr (narrow_integral) {
-                                res = (vec_from[i].value + multiplier / 2) / 
multiplier;
-                                if (UNLIKELY(res > max_result.value)) {
-                                    throw 
Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
-                                                    "Arithmetic overflow, 
convert failed from {}, "
-                                                    "expected data is [{}, 
{}]",
-                                                    res, -max_result.value, 
max_result.value);
-                                }
-                                vec_to[i] = ToFieldType(res);
-                            } else {
-                                vec_to[i] = ToFieldType((vec_from[i].value + 
multiplier / 2) /
-                                                        multiplier);
-                            }
-                        } else {
-                            if constexpr (narrow_integral) {
-                                res = (vec_from[i].value - multiplier / 2) / 
multiplier;
-                                if (UNLIKELY(res < -max_result.value)) {
-                                    throw 
Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
-                                                    "Arithmetic overflow, 
convert failed from {}, "
-                                                    "expected data is [{}, 
{}]",
-                                                    res, -max_result.value, 
max_result.value);
-                                }
-                                vec_to[i] = ToFieldType(res);
-                            } else {
-                                vec_to[i] = ToFieldType((vec_from[i].value - 
multiplier / 2) /
-                                                        multiplier);
-                            }
-                        }
+        for (size_t i = 0; i < sz; i++) {
+            if (vec_from[i] >= FromFieldType(0)) {
+                if constexpr (narrow_integral) {
+                    res = (vec_from[i].value + multiplier / 2) / multiplier;
+                    if (UNLIKELY(res > max_result.value)) {
+                        throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
+                                        "Arithmetic overflow, convert failed 
from {}, "
+                                        "expected data is [{}, {}]",
+                                        res, -max_result.value, 
max_result.value);
                     }
-                },
-                make_bool_variant(narrow_integral));
+                    vec_to[i] = ToFieldType(res);
+                } else {
+                    vec_to[i] = ToFieldType((vec_from[i].value + multiplier / 
2) / multiplier);
+                }
+            } else {
+                if constexpr (narrow_integral) {
+                    res = (vec_from[i].value - multiplier / 2) / multiplier;
+                    if (UNLIKELY(res < -max_result.value)) {
+                        throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
+                                        "Arithmetic overflow, convert failed 
from {}, "
+                                        "expected data is [{}, {}]",
+                                        res, -max_result.value, 
max_result.value);
+                    }
+                    vec_to[i] = ToFieldType(res);
+                } else {
+                    vec_to[i] = ToFieldType((vec_from[i].value - multiplier / 
2) / multiplier);
+                }
+            }
+        }
     }
 }
 
 template <typename FromDataType, typename ToDataType, bool narrow_integral>
-    requires IsDataTypeDecimal<FromDataType> && IsDataTypeNumber<ToDataType>
-ToDataType::FieldType convert_from_decimal(const typename 
FromDataType::FieldType& value,
-                                           UInt32 scale,
-                                           const typename 
ToDataType::FieldType& min_result,
-                                           const typename 
ToDataType::FieldType& max_result) {
+    requires IsDataTypeDecimal<FromDataType>
+void convert_from_decimal(typename ToDataType::FieldType* dst,
+                          const typename FromDataType::FieldType* src, UInt32 
scale,
+                          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;
 
     if constexpr (std::is_floating_point_v<ToFieldType>) {
         if constexpr (IsDecimalV2<FromFieldType>) {
-            return binary_cast<int128_t, DecimalV2Value>(value);
+            for (size_t i = 0; i < size; ++i) {
+                dst[i] = binary_cast<int128_t, DecimalV2Value>(src[i]);
+            }
         } else {
-            return static_cast<ToFieldType>(value.value) /
-                   FromDataType::get_scale_multiplier(scale).value;
+            auto multiplier = FromDataType::get_scale_multiplier(scale);
+            for (size_t i = 0; i < size; ++i) {
+                dst[i] = static_cast<ToFieldType>(src[i].value) / 
multiplier.value;
+            }
+        }
+        if constexpr (narrow_integral) {
+            for (size_t i = 0; i < size; i++) {
+                if (dst[i] < min_result || dst[i] > max_result) {
+                    throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
+                                    "Arithmetic overflow, convert failed from 
{}, "
+                                    "expected data is [{}, {}]",
+                                    dst[i], min_result, max_result);
+                }
+            }
         }
     } else {
-        return convert_decimals<FromDataType, FromDataType, false, 
narrow_integral>(
-                value, scale, 0, FromFieldType(min_result), 
FromFieldType(max_result));
+        convert_from_decimals<FromDataType, FromDataType, narrow_integral>(
+                dst, src, scale, FromFieldType(min_result), 
FromFieldType(max_result), size);
     }
 }
 
 template <typename FromDataType, typename ToDataType, bool 
multiply_may_overflow,
           bool narrow_integral>
-    requires IsDataTypeNumber<FromDataType> && IsDataTypeDecimal<ToDataType>
-ToDataType::FieldType convert_to_decimal(const typename 
FromDataType::FieldType& value,
-                                         UInt32 from_scale, UInt32 to_scale,
-                                         const typename ToDataType::FieldType& 
min_result,
-                                         const typename ToDataType::FieldType& 
max_result) {
+    requires IsDataTypeDecimal<ToDataType>
+void convert_to_decimal(typename ToDataType::FieldType* dst,
+                        const typename FromDataType::FieldType* src, UInt32 
from_scale,
+                        UInt32 to_scale, const typename ToDataType::FieldType& 
min_result,
+                        const typename ToDataType::FieldType& max_result, 
size_t size) {
     using FromFieldType = typename FromDataType::FieldType;
 
     if constexpr (std::is_floating_point_v<FromFieldType>) {
-        if (!std::isfinite(value)) {
-            VLOG_DEBUG << "Decimal convert overflow. Cannot convert infinity 
or NaN to decimal";
-            throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR, "Arithmetic 
overflow");
-        }
-
-        FromFieldType out;
-        out = value * ToDataType::get_scale_multiplier(to_scale);
-        if (out <= static_cast<FromFieldType>(-max_result) ||
-            out >= static_cast<FromFieldType>(max_result)) {
-            VLOG_DEBUG << "Decimal convert overflow. Float is out of Decimal 
range";
-            throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR, "Arithmetic 
overflow");
-        }
-        return typename ToDataType::FieldType(out);
-    } else {
-        if constexpr (std::is_same_v<FromFieldType, UInt64>) {
-            if (value > 
static_cast<UInt64>(std::numeric_limits<Int64>::max())) {
-                return convert_decimals<DataTypeDecimal<Decimal128>, 
ToDataType,
-                                        multiply_may_overflow, 
narrow_integral>(
-                        value, from_scale, to_scale, min_result, max_result);
+        auto multiplier = ToDataType::get_scale_multiplier(to_scale);
+        if constexpr (narrow_integral) {
+            for (size_t i = 0; i < size; ++i) {
+                if (!std::isfinite(src[i])) {
+                    throw Exception(
+                            ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
+                            "Decimal convert overflow. Cannot convert infinity 
or NaN to decimal");
+                }
+                FromFieldType tmp = src[i] * multiplier;
+                if (tmp <= FromFieldType(min_result) || tmp >= 
FromFieldType(max_result)) {
+                    throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
+                                    "Arithmetic overflow, convert failed from 
{}, "
+                                    "expected data is [{}, {}]",
+                                    FromFieldType(tmp), 
FromFieldType(min_result),
+                                    FromFieldType(max_result));
+                }
             }
         }
-        if constexpr (std::is_same_v<FromFieldType, Int128>) {
-            return convert_decimals<DataTypeDecimal<Decimal128>, ToDataType, 
multiply_may_overflow,
-                                    narrow_integral>(value, from_scale, 
to_scale, min_result,
-                                                     max_result);
-        }
-
-        if constexpr (std::is_same_v<FromFieldType, wide::Int256>) {
-            return convert_decimals<DataTypeDecimal<Decimal256>, ToDataType, 
multiply_may_overflow,
-                                    narrow_integral>(value, from_scale, 
to_scale, min_result,
-                                                     max_result);
+        for (size_t i = 0; i < size; ++i) {
+            dst[i].value = FromFieldType(src[i] * multiplier.value + ((src[i] 
>= 0) ? 0.5 : -0.5));
         }
-        return convert_decimals<DataTypeDecimal<Decimal64>, ToDataType, 
multiply_may_overflow,
-                                narrow_integral>(value, from_scale, to_scale, 
min_result,
-                                                 max_result);
+    } else {
+        using DecimalFrom =
+                std::conditional_t<std::is_same_v<FromFieldType, Int128>, 
Decimal128,
+                                   
std::conditional_t<std::is_same_v<FromFieldType, wide::Int256>,
+                                                      Decimal256, Decimal64>>;
+        convert_to_decimals<DataTypeDecimal<DecimalFrom>, ToDataType, 
multiply_may_overflow,
+                            narrow_integral>(dst, src, from_scale, to_scale, 
min_result, max_result,
+                                             size);
     }
 }
 
diff --git a/be/src/vec/data_types/number_traits.h 
b/be/src/vec/data_types/number_traits.h
index 0990208c4c3..4f97a266766 100644
--- a/be/src/vec/data_types/number_traits.h
+++ b/be/src/vec/data_types/number_traits.h
@@ -20,6 +20,7 @@
 
 #pragma once
 
+#include <climits>
 #include <type_traits>
 
 #include "vec/columns/column_decimal.h"
@@ -220,7 +221,6 @@ template <typename T>
 /// Returns the maximum ascii string length for this type.
 /// e.g. the max/min int8_t has 3 characters.
 int max_ascii_len() {
-    LOG(FATAL) << "Not implemented.";
     return 0;
 }
 
@@ -273,6 +273,16 @@ template <>
 inline int max_ascii_len<wide::Int256>() {
     return 77;
 }
+
+template <>
+inline int max_ascii_len<float>() {
+    return INT_MAX;
+}
+
+template <>
+inline int max_ascii_len<double>() {
+    return INT_MAX;
+}
 } // namespace NumberTraits
 
 } // namespace doris::vectorized
diff --git a/be/src/vec/functions/function_binary_arithmetic.h 
b/be/src/vec/functions/function_binary_arithmetic.h
index 844d60b8e84..30ede75ea17 100644
--- a/be/src/vec/functions/function_binary_arithmetic.h
+++ b/be/src/vec/functions/function_binary_arithmetic.h
@@ -239,6 +239,11 @@ struct DecimalBinaryOperation {
     using ArrayC = typename ColumnDecimal<ResultType>::Container;
 
 private:
+    template <typename T>
+    static int8_t sgn(const T& x) {
+        return (x > 0) ? 1 : ((x < 0) ? -1 : 0);
+    }
+
     static void vector_vector(const typename Traits::ArrayA::value_type* 
__restrict a,
                               const typename Traits::ArrayB::value_type* 
__restrict b,
                               typename ArrayC::value_type* c, size_t size,
@@ -257,7 +262,17 @@ private:
                                     a[i], b[i], max_result_number, 
scale_diff_multiplier));
                         }
                     },
-                    make_bool_variant(need_adjust_scale));
+                    make_bool_variant(need_adjust_scale && check_overflow));
+
+            if (OpTraits::is_multiply && need_adjust_scale && !check_overflow) 
{
+                int8_t sig[size];
+                for (size_t i = 0; i < size; i++) {
+                    sig[i] = sgn(c[i].value);
+                }
+                for (size_t i = 0; i < size; i++) {
+                    c[i].value = (c[i].value - sig[i]) / 
scale_diff_multiplier.value + sig[i];
+                }
+            }
         }
     }
 
diff --git a/be/src/vec/functions/function_cast.h 
b/be/src/vec/functions/function_cast.h
index 48428333c77..2e1e48db14d 100644
--- a/be/src/vec/functions/function_cast.h
+++ b/be/src/vec/functions/function_cast.h
@@ -256,9 +256,8 @@ struct ConvertImpl {
 
     template <typename Additions = void*>
     static Status execute(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
-                          size_t result, size_t /*input_rows_count*/,
-                          bool check_overflow [[maybe_unused]] = false,
-                          Additions additions [[maybe_unused]] = Additions()) {
+                          size_t result, size_t input_rows_count,
+                          Additions additions = Additions()) {
         const ColumnWithTypeAndName& named_from = 
block.get_by_position(arguments[0]);
 
         using ColVecFrom =
@@ -278,7 +277,7 @@ struct ConvertImpl {
         if (const ColVecFrom* col_from =
                     check_and_get_column<ColVecFrom>(named_from.column.get())) 
{
             typename ColVecTo::MutablePtr col_to = nullptr;
-            UInt32 from_precision = 0;
+            UInt32 from_precision = 
NumberTraits::max_ascii_len<FromFieldType>();
             UInt32 from_scale = 0;
 
             if constexpr (IsDataTypeDecimal<FromDataType>) {
@@ -286,9 +285,6 @@ struct ConvertImpl {
                 from_precision = from_decimal_type.get_precision();
                 from_scale = from_decimal_type.get_scale();
             }
-            if constexpr (std::is_integral_v<FromFieldType>) {
-                from_precision = NumberTraits::max_ascii_len<FromFieldType>();
-            }
 
             UInt32 to_max_digits = 0;
             UInt32 to_precision = 0;
@@ -326,71 +322,37 @@ struct ConvertImpl {
             vec_to.resize(size);
 
             if constexpr (IsDataTypeDecimal<FromDataType> || 
IsDataTypeDecimal<ToDataType>) {
-                bool narrow_integral = (to_precision - to_scale) < 
(from_precision - from_scale);
+                bool narrow_integral = context->check_overflow_for_decimal() &&
+                                       (to_precision - to_scale) < 
(from_precision - from_scale);
 
-                bool multiply_may_overflow = false;
+                bool multiply_may_overflow = 
context->check_overflow_for_decimal();
                 if (to_scale > from_scale) {
-                    multiply_may_overflow =
-                            (from_precision + to_scale - from_scale) > 
to_max_digits;
+                    multiply_may_overflow &=
+                            (from_precision + to_scale - from_scale) >= 
to_max_digits;
                 }
 
-                if constexpr (IsDataTypeDecimal<FromDataType> && 
IsDataTypeDecimal<ToDataType>) {
-                    convert_decimal_cols<FromDataType, ToDataType>(
-                            vec_from.data(), vec_to.data(), from_precision, 
vec_from.get_scale(),
-                            to_precision, vec_to.get_scale(), vec_from.size());
-                } else {
-                    std::visit(
-                            [&](auto multiply_may_overflow, auto 
narrow_integral) {
-                                for (size_t i = 0; i < size; ++i) {
-                                    if constexpr 
(IsDataTypeDecimal<FromDataType> &&
-                                                  
IsDataTypeNumber<ToDataType>) {
-                                        vec_to[i] = 
convert_from_decimal<FromDataType, ToDataType,
-                                                                         
narrow_integral>(
-                                                vec_from[i], 
vec_from.get_scale(), min_result,
-                                                max_result);
-                                    } else if constexpr 
(IsDataTypeNumber<FromDataType> &&
-                                                         
IsDataTypeDecimal<ToDataType>) {
-                                        vec_to[i] = 
convert_to_decimal<FromDataType, ToDataType,
-                                                                       
multiply_may_overflow,
-                                                                       
narrow_integral>(
-                                                vec_from[i], from_scale, 
to_scale, min_result,
-                                                max_result);
-                                    } else if constexpr 
(IsTimeType<FromDataType> &&
-                                                         
IsDataTypeDecimal<ToDataType>) {
-                                        vec_to[i] = 
convert_to_decimal<DataTypeInt64, ToDataType,
-                                                                       
multiply_may_overflow,
-                                                                       
narrow_integral>(
-                                                reinterpret_cast<const 
VecDateTimeValue&>(
-                                                        vec_from[i])
-                                                        .to_int64(),
-                                                from_scale, to_scale, 
min_result, max_result);
-                                    } else if constexpr 
(IsDateV2Type<FromDataType> &&
-                                                         
IsDataTypeDecimal<ToDataType>) {
-                                        vec_to[i] = 
convert_to_decimal<DataTypeUInt32, ToDataType,
-                                                                       
multiply_may_overflow,
-                                                                       
narrow_integral>(
-                                                reinterpret_cast<
-                                                        const 
DateV2Value<DateV2ValueType>&>(
-                                                        vec_from[i])
-                                                        .to_date_int_val(),
-                                                from_scale, to_scale, 
min_result, max_result);
-                                    } else if constexpr 
(IsDateTimeV2Type<FromDataType> &&
-                                                         
IsDataTypeDecimal<ToDataType>) {
-                                        // TODO: should we consider the scale 
of datetimev2?
-                                        vec_to[i] = 
convert_to_decimal<DataTypeUInt64, ToDataType,
-                                                                       
multiply_may_overflow,
-                                                                       
narrow_integral>(
-                                                reinterpret_cast<
-                                                        const 
DateV2Value<DateTimeV2ValueType>&>(
-                                                        vec_from[i])
-                                                        .to_date_int_val(),
-                                                from_scale, to_scale, 
min_result, max_result);
-                                    }
-                                }
-                            },
-                            make_bool_variant(multiply_may_overflow),
-                            make_bool_variant(narrow_integral));
-                }
+                std::visit(
+                        [&](auto multiply_may_overflow, auto narrow_integral) {
+                            if constexpr (IsDataTypeDecimal<FromDataType> &&
+                                          IsDataTypeDecimal<ToDataType>) {
+                                convert_decimal_cols<FromDataType, ToDataType,
+                                                     multiply_may_overflow, 
narrow_integral>(
+                                        vec_from.data(), vec_to.data(), 
from_precision,
+                                        vec_from.get_scale(), to_precision, 
vec_to.get_scale(),
+                                        vec_from.size());
+                            } else if constexpr 
(IsDataTypeDecimal<FromDataType>) {
+                                convert_from_decimal<FromDataType, ToDataType, 
narrow_integral>(
+                                        vec_to.data(), vec_from.data(), 
vec_from.get_scale(),
+                                        min_result, max_result, size);
+                            } else {
+                                convert_to_decimal<FromDataType, ToDataType, 
multiply_may_overflow,
+                                                   
narrow_integral>(vec_to.data(), vec_from.data(),
+                                                                    
from_scale, to_scale,
+                                                                    
min_result, max_result, size);
+                            }
+                        },
+                        make_bool_variant(multiply_may_overflow),
+                        make_bool_variant(narrow_integral));
 
                 block.replace_by_position(result, std::move(col_to));
 
@@ -546,22 +508,11 @@ struct ConvertImplToTimeType {
                 from_scale = from_decimal_type.get_scale();
             }
             bool narrow_integral = to_precision < (from_precision - 
from_scale);
-            auto max_result = type_limit<DataTypeInt64::FieldType>::max();
-            auto min_result = type_limit<DataTypeInt64::FieldType>::min();
             std::visit(
                     [&](auto narrow_integral) {
                         for (size_t i = 0; i < size; ++i) {
                             auto& date_value = 
reinterpret_cast<DateValueType&>(vec_to[i]);
-                            if constexpr (IsDecimalNumber<FromFieldType>) {
-                                // TODO: should we consider the scale of 
datetimev2?
-                                vec_null_map_to[i] = 
!date_value.from_date_int64(
-                                        convert_from_decimal<FromDataType, 
DataTypeInt64,
-                                                             narrow_integral>(
-                                                vec_from[i], 
vec_from.get_scale(), min_result,
-                                                max_result));
-                            } else {
-                                vec_null_map_to[i] = 
!date_value.from_date_int64(vec_from[i]);
-                            }
+                            vec_null_map_to[i] = 
!date_value.from_date_int64(vec_from[i]);
                             // DateType of VecDateTimeValue should cast to date
                             if constexpr (IsDateType<ToDataType>) {
                                 date_value.cast_to_date();
@@ -958,8 +909,7 @@ struct ConvertImpl<DataTypeString, ToDataType, Name> {
     template <typename Additions = void*>
 
     static Status execute(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
-                          size_t result, size_t /*input_rows_count*/,
-                          bool check_overflow [[maybe_unused]] = false,
+                          size_t result, size_t input_rows_count,
                           Additions additions [[maybe_unused]] = Additions()) {
         return Status::RuntimeError("not support convert from string");
     }
@@ -1325,12 +1275,12 @@ public:
 
                     const ColumnWithTypeAndName& scale_column = 
block.get_by_position(result);
                     ret_status = ConvertImpl<LeftDataType, RightDataType, 
Name>::execute(
-                            context, block, arguments, result, 
input_rows_count, false,
+                            context, block, arguments, result, 
input_rows_count,
                             scale_column.type->get_scale());
                 } else if constexpr (IsDataTypeDateTimeV2<RightDataType>) {
                     const ColumnWithTypeAndName& scale_column = 
block.get_by_position(result);
                     ret_status = ConvertImpl<LeftDataType, RightDataType, 
Name>::execute(
-                            context, block, arguments, result, 
input_rows_count, false,
+                            context, block, arguments, result, 
input_rows_count,
                             scale_column.type->get_scale());
                 } else {
                     ret_status = ConvertImpl<LeftDataType, RightDataType, 
Name>::execute(
@@ -1535,7 +1485,6 @@ struct ConvertThroughParsing {
     template <typename Additions = void*>
     static Status execute(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
                           size_t result, size_t input_rows_count,
-                          bool check_overflow [[maybe_unused]] = false,
                           Additions additions [[maybe_unused]] = Additions()) {
         using ColVecTo = std::conditional_t<IsDecimalNumber<ToFieldType>,
                                             ColumnDecimal<ToFieldType>, 
ColumnVector<ToFieldType>>;
@@ -1838,7 +1787,7 @@ private:
                         using RightDataType = typename Types::RightType;
 
                         auto state = ConvertImpl<LeftDataType, RightDataType, 
NameCast>::execute(
-                                context, block, arguments, result, 
input_rows_count, false,
+                                context, block, arguments, result, 
input_rows_count,
                                 PrecisionScaleArg {precision, scale});
                         if (!state) {
                             throw Exception(state.code(), state.to_string());
diff --git a/be/src/vec/functions/function_math_log.h 
b/be/src/vec/functions/function_math_log.h
new file mode 100644
index 00000000000..e8653e4220d
--- /dev/null
+++ b/be/src/vec/functions/function_math_log.h
@@ -0,0 +1,92 @@
+
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#pragma once
+
+#include "vec/columns/columns_number.h"
+#include "vec/common/assert_cast.h"
+#include "vec/core/types.h"
+#include "vec/data_types/data_type_number.h"
+#include "vec/functions/function.h"
+
+namespace doris::vectorized {
+
+template <typename Impl>
+class FunctionMathLog : public IFunction {
+public:
+    using IFunction::execute;
+
+    static constexpr auto name = Impl::name;
+    static FunctionPtr create() { return std::make_shared<FunctionMathLog>(); }
+
+private:
+    String get_name() const override { return name; }
+    size_t get_number_of_arguments() const override { return 1; }
+
+    DataTypePtr get_return_type_impl(const DataTypes& arguments) const 
override {
+        return make_nullable(std::make_shared<DataTypeFloat64>());
+    }
+
+    static void execute_in_iterations(const double* src_data, double* 
dst_data, NullMap& null_map,
+                                      size_t size) {
+        for (size_t i = 0; i < size; i++) {
+            null_map[i] = src_data[i] <= 0;
+            Impl::execute(&src_data[i], &dst_data[i]);
+        }
+    }
+
+    Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
+                        size_t result, size_t input_rows_count) const override 
{
+        const auto* col =
+                assert_cast<const 
ColumnFloat64*>(block.get_by_position(arguments[0]).column.get());
+
+        const auto& src_data = col->get_data();
+        const size_t size = src_data.size();
+
+        auto dst = ColumnFloat64::create();
+        auto& dst_data = dst->get_data();
+        dst_data.resize(size);
+
+        auto null_column = ColumnVector<UInt8>::create();
+        auto& null_map = null_column->get_data();
+        null_map.resize(size);
+
+        execute_in_iterations(col->get_data().data(), dst_data.data(), 
null_map, size);
+
+        block.replace_by_position(result,
+                                  ColumnNullable::create(std::move(dst), 
std::move(null_column)));
+        return Status::OK();
+    }
+};
+
+struct ImplLog10 {
+    static constexpr auto name = "log10";
+    static void execute(const double* src, double* dst) { *dst = 
std::log10(*src); }
+};
+
+struct ImplLog2 {
+    static constexpr auto name = "log2";
+    static void execute(const double* src, double* dst) { *dst = 
std::log2(*src); }
+};
+
+struct ImplLn {
+    static constexpr auto name = "ln";
+    static void execute(const double* src, double* dst) { *dst = 
std::log(*src); }
+};
+
+} // namespace doris::vectorized
diff --git a/be/src/vec/functions/function_math_unary.h 
b/be/src/vec/functions/function_math_unary.h
index 0d7544a7769..e5101692b86 100644
--- a/be/src/vec/functions/function_math_unary.h
+++ b/be/src/vec/functions/function_math_unary.h
@@ -37,8 +37,6 @@ public:
     using IFunction::execute;
 
     static constexpr auto name = Impl::name;
-    static constexpr bool has_variadic_argument =
-            
!std::is_void_v<decltype(has_variadic_argument_types(std::declval<Impl>()))>;
     static FunctionPtr create() { return 
std::make_shared<FunctionMathUnary>(); }
 
 private:
@@ -46,145 +44,43 @@ private:
     size_t get_number_of_arguments() const override { return 1; }
 
     DataTypePtr get_return_type_impl(const DataTypes& arguments) const 
override {
-        const auto& arg = arguments.front();
-        if (!is_number(arg)) {
-            return nullptr;
-        }
         return std::make_shared<typename Impl::Type>();
     }
 
-    DataTypes get_variadic_argument_types_impl() const override {
-        if constexpr (has_variadic_argument) return 
Impl::get_variadic_argument_types();
-        return {};
-    }
-
-    template <typename T, typename ReturnType>
-    static void execute_in_iterations(const T* src_data, ReturnType* dst_data, 
size_t size) {
-        if constexpr (Impl::rows_per_iteration == 0) {
-            /// Process all data as a whole and use FastOps implementation
-
-            /// If the argument is integer, convert to Float64 beforehand
-            if constexpr (!std::is_floating_point_v<T>) {
-                PODArray<Float64> tmp_vec(size);
-                for (size_t i = 0; i < size; ++i) tmp_vec[i] = src_data[i];
-
-                Impl::execute(tmp_vec.data(), size, dst_data);
-            } else {
-                Impl::execute(src_data, size, dst_data);
-            }
-        } else {
-            const size_t rows_remaining = size % Impl::rows_per_iteration;
-            const size_t rows_size = size - rows_remaining;
-
-            for (size_t i = 0; i < rows_size; i += Impl::rows_per_iteration)
-                Impl::execute(&src_data[i], &dst_data[i]);
-
-            if (rows_remaining != 0) {
-                T src_remaining[Impl::rows_per_iteration];
-                memcpy(src_remaining, &src_data[rows_size], rows_remaining * 
sizeof(T));
-                memset(src_remaining + rows_remaining, 0,
-                       (Impl::rows_per_iteration - rows_remaining) * 
sizeof(T));
-                ReturnType dst_remaining[Impl::rows_per_iteration];
-
-                Impl::execute(src_remaining, dst_remaining);
-
-                memcpy(&dst_data[rows_size], dst_remaining, rows_remaining * 
sizeof(ReturnType));
-            }
+    static void execute_in_iterations(const double* src_data, double* 
dst_data, size_t size) {
+        for (size_t i = 0; i < size; i++) {
+            Impl::execute(&src_data[i], &dst_data[i]);
         }
     }
 
-    template <typename T, typename ReturnType>
-    static bool execute(Block& block, const ColumnVector<T>* col, UInt32, 
UInt32,
-                        const size_t result) {
-        const auto& src_data = col->get_data();
-        const size_t size = src_data.size();
-
-        auto dst = ColumnVector<ReturnType>::create();
-        auto& dst_data = dst->get_data();
-        dst_data.resize(size);
-
-        execute_in_iterations(src_data.data(), dst_data.data(), size);
-
-        block.replace_by_position(result, std::move(dst));
-        return true;
-    }
+    Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
+                        size_t result, size_t input_rows_count) const override 
{
+        const auto* col =
+                assert_cast<const 
ColumnFloat64*>(block.get_by_position(arguments[0]).column.get());
 
-    template <typename T, typename ReturnType>
-    static bool execute(Block& block, const ColumnDecimal<T>* col, UInt32 
from_precision,
-                        UInt32 from_scale, const size_t result) {
         const auto& src_data = col->get_data();
         const size_t size = src_data.size();
-        UInt32 scale = src_data.get_scale();
 
-        auto dst = ColumnVector<ReturnType>::create();
+        auto dst = ColumnFloat64::create();
         auto& dst_data = dst->get_data();
         dst_data.resize(size);
 
-        UInt32 to_precision = NumberTraits::max_ascii_len<ReturnType>();
-        bool narrow_integral = to_precision < (from_precision - from_scale);
-        auto max_result = type_limit<ReturnType>::max();
-        auto min_result = type_limit<ReturnType>::min();
-
-        std::visit(
-                [&](auto narrow_integral) {
-                    for (size_t i = 0; i < size; ++i)
-                        dst_data[i] =
-                                convert_from_decimal<DataTypeDecimal<T>, 
DataTypeNumber<ReturnType>,
-                                                     
narrow_integral>(src_data[i], scale,
-                                                                      
min_result, max_result);
-                },
-                make_bool_variant(narrow_integral));
-
-        execute_in_iterations(dst_data.data(), dst_data.data(), size);
+        execute_in_iterations(col->get_data().data(), dst_data.data(), size);
 
         block.replace_by_position(result, std::move(dst));
-        return true;
-    }
-
-    Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
-                        size_t result, size_t input_rows_count) const override 
{
-        const ColumnWithTypeAndName& col = block.get_by_position(arguments[0]);
-
-        auto call = [&](const auto& types) -> bool {
-            using Types = std::decay_t<decltype(types)>;
-            using Type = typename Types::RightType;
-            using ReturnType = 
std::conditional_t<Impl::always_returns_float64, Float64, Int64>;
-            using ColVecType = std::conditional_t<IsDecimalNumber<Type>, 
ColumnDecimal<Type>,
-                                                  ColumnVector<Type>>;
-
-            UInt32 from_precision = 0;
-            UInt32 from_scale = 0;
-            if constexpr (IsDecimalNumber<Type>) {
-                const auto& from_decimal_type =
-                        assert_cast<const DataTypeDecimal<Type>&>(*col.type);
-                from_precision = from_decimal_type.get_precision();
-                from_scale = from_decimal_type.get_scale();
-            }
-            const auto col_vec = 
check_and_get_column<ColVecType>(col.column.get());
-            return execute<Type, ReturnType>(block, col_vec, from_precision, 
from_scale, result);
-        };
-
-        if (!call_on_basic_type<void, true, true, true, 
false>(col.type->get_type_id(), call)) {
-            return Status::InvalidArgument("Illegal column {} of argument of 
function {}",
-                                           col.column->get_name(), get_name());
-        }
         return Status::OK();
     }
 };
 
-template <typename Name, Float64(Function)(Float64), typename ReturnType = 
DataTypeFloat64>
+template <typename Name, Float64(Function)(Float64)>
 struct UnaryFunctionPlain {
-    using Type = ReturnType;
+    using Type = DataTypeFloat64;
     static constexpr auto name = Name::name;
-    static constexpr auto rows_per_iteration = 1;
-    static constexpr bool always_returns_float64 = std::is_same_v<Type, 
DataTypeFloat64>;
 
     template <typename T, typename U>
     static void execute(const T* src, U* dst) {
-        dst[0] = static_cast<Float64>(Function(static_cast<Float64>(src[0])));
+        *dst = static_cast<Float64>(Function(*src));
     }
 };
 
-#define UnaryFunctionVectorized UnaryFunctionPlain
-
 } // namespace doris::vectorized
diff --git a/be/src/vec/functions/function_math_unary_to_null_type.h 
b/be/src/vec/functions/function_math_unary_to_null_type.h
deleted file mode 100644
index c4833cb6c6f..00000000000
--- a/be/src/vec/functions/function_math_unary_to_null_type.h
+++ /dev/null
@@ -1,148 +0,0 @@
-
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-#pragma once
-
-#include "vec/columns/column_decimal.h"
-#include "vec/columns/columns_number.h"
-#include "vec/core/types.h"
-#include "vec/data_types/data_type_decimal.h"
-#include "vec/data_types/data_type_number.h"
-#include "vec/functions/function.h"
-#include "vec/functions/function_helpers.h"
-
-namespace doris::vectorized {
-
-template <typename Impl>
-class FunctionMathUnaryToNullType : public IFunction {
-public:
-    using IFunction::execute;
-
-    static constexpr auto name = Impl::name;
-    static FunctionPtr create() { return 
std::make_shared<FunctionMathUnaryToNullType>(); }
-
-private:
-    String get_name() const override { return name; }
-    size_t get_number_of_arguments() const override { return 1; }
-
-    DataTypePtr get_return_type_impl(const DataTypes& arguments) const 
override {
-        const auto& arg = arguments.front();
-        if (!is_number(arg)) {
-            return nullptr;
-        }
-        return make_nullable(std::make_shared<typename Impl::Type>());
-    }
-
-    template <typename T, typename ReturnType>
-    static void execute_in_iterations(const T* src_data, ReturnType* dst_data, 
NullMap& null_map,
-                                      size_t size) {
-        for (size_t i = 0; i < size; i++) {
-            Impl::execute(&src_data[i], &dst_data[i], null_map[i]);
-        }
-    }
-
-    template <typename T, typename ReturnType>
-    static bool execute(Block& block, const ColumnVector<T>* col, UInt32, 
UInt32,
-                        const size_t result) {
-        const auto& src_data = col->get_data();
-        const size_t size = src_data.size();
-
-        auto dst = ColumnVector<ReturnType>::create();
-        auto& dst_data = dst->get_data();
-        dst_data.resize(size);
-
-        auto null_column = ColumnVector<UInt8>::create();
-        auto& null_map = null_column->get_data();
-        null_map.resize(size);
-
-        execute_in_iterations(src_data.data(), dst_data.data(), null_map, 
size);
-
-        block.replace_by_position(result,
-                                  ColumnNullable::create(std::move(dst), 
std::move(null_column)));
-        return true;
-    }
-
-    template <typename T, typename ReturnType>
-    static bool execute(Block& block, const ColumnDecimal<T>* col, UInt32 
from_precision,
-                        UInt32 from_scale, const size_t result) {
-        const auto& src_data = col->get_data();
-        const size_t size = src_data.size();
-        UInt32 scale = src_data.get_scale();
-
-        auto dst = ColumnVector<ReturnType>::create();
-        auto& dst_data = dst->get_data();
-        dst_data.resize(size);
-
-        auto null_column = ColumnVector<UInt8>::create();
-        auto& null_map = null_column->get_data();
-        null_map.resize(size);
-
-        UInt32 to_precision = NumberTraits::max_ascii_len<ReturnType>();
-        bool narrow_integral = to_precision < (from_precision - from_scale);
-        auto max_result = type_limit<ReturnType>::max();
-        auto min_result = type_limit<ReturnType>::min();
-        std::visit(
-                [&](auto narrow_integral) {
-                    for (size_t i = 0; i < size; ++i) {
-                        dst_data[i] =
-                                convert_from_decimal<DataTypeDecimal<T>, 
DataTypeNumber<ReturnType>,
-                                                     
narrow_integral>(src_data[i], scale,
-                                                                      
min_result, max_result);
-                    }
-                },
-                make_bool_variant(narrow_integral));
-
-        execute_in_iterations(dst_data.data(), dst_data.data(), null_map, 
size);
-
-        block.replace_by_position(result,
-                                  ColumnNullable::create(std::move(dst), 
std::move(null_column)));
-        return true;
-    }
-
-    Status execute_impl(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
-                        size_t result, size_t input_rows_count) const override 
{
-        const ColumnWithTypeAndName& col = block.get_by_position(arguments[0]);
-
-        auto call = [&](const auto& types) -> bool {
-            using Types = std::decay_t<decltype(types)>;
-            using Type = typename Types::RightType;
-            using ColVecType = std::conditional_t<IsDecimalNumber<Type>, 
ColumnDecimal<Type>,
-                                                  ColumnVector<Type>>;
-            UInt32 from_precision = 0;
-            UInt32 from_scale = 0;
-            if constexpr (IsDecimalNumber<Type>) {
-                const auto& from_decimal_type =
-                        assert_cast<const DataTypeDecimal<Type>&>(*col.type);
-                from_precision = from_decimal_type.get_precision();
-                from_scale = from_decimal_type.get_scale();
-            }
-
-            const auto col_vec = 
check_and_get_column<ColVecType>(col.column.get());
-            return execute<Type, typename Impl::RetType>(block, col_vec, 
from_precision, from_scale,
-                                                         result);
-        };
-
-        if (!call_on_basic_type<void, true, true, true, 
false>(col.type->get_type_id(), call)) {
-            return Status::InvalidArgument("Illegal column {} of argument of 
function {}",
-                                           col.column->get_name(), get_name());
-        }
-        return Status::OK();
-    }
-};
-
-} // namespace doris::vectorized
diff --git a/be/src/vec/functions/math.cpp b/be/src/vec/functions/math.cpp
index 298a765aa11..98cfc65e2f4 100644
--- a/be/src/vec/functions/math.cpp
+++ b/be/src/vec/functions/math.cpp
@@ -42,8 +42,8 @@
 #include "vec/data_types/number_traits.h"
 #include "vec/functions/function_binary_arithmetic.h"
 #include "vec/functions/function_const.h"
+#include "vec/functions/function_math_log.h"
 #include "vec/functions/function_math_unary.h"
-#include "vec/functions/function_math_unary_to_null_type.h"
 #include "vec/functions/function_string.h"
 #include "vec/functions/function_totype.h"
 #include "vec/functions/function_unary_arithmetic.h"
@@ -62,22 +62,22 @@ namespace doris::vectorized {
 struct AcosName {
     static constexpr auto name = "acos";
 };
-using FunctionAcos = FunctionMathUnary<UnaryFunctionVectorized<AcosName, 
std::acos>>;
+using FunctionAcos = FunctionMathUnary<UnaryFunctionPlain<AcosName, 
std::acos>>;
 
 struct AsinName {
     static constexpr auto name = "asin";
 };
-using FunctionAsin = FunctionMathUnary<UnaryFunctionVectorized<AsinName, 
std::asin>>;
+using FunctionAsin = FunctionMathUnary<UnaryFunctionPlain<AsinName, 
std::asin>>;
 
 struct AtanName {
     static constexpr auto name = "atan";
 };
-using FunctionAtan = FunctionMathUnary<UnaryFunctionVectorized<AtanName, 
std::atan>>;
+using FunctionAtan = FunctionMathUnary<UnaryFunctionPlain<AtanName, 
std::atan>>;
 
 struct CosName {
     static constexpr auto name = "cos";
 };
-using FunctionCos = FunctionMathUnary<UnaryFunctionVectorized<CosName, 
std::cos>>;
+using FunctionCos = FunctionMathUnary<UnaryFunctionPlain<CosName, std::cos>>;
 
 struct EImpl {
     static constexpr auto name = "e";
@@ -94,24 +94,7 @@ using FunctionPi = FunctionMathConstFloat64<PiImpl>;
 struct ExpName {
     static constexpr auto name = "exp";
 };
-using FunctionExp = FunctionMathUnary<UnaryFunctionVectorized<ExpName, 
std::exp>>;
-
-#define LOG_FUNCTION_IMPL(CLASS, NAME, FUNC)                          \
-    struct CLASS##Impl {                                              \
-        using Type = DataTypeFloat64;                                 \
-        using RetType = Float64;                                      \
-        static constexpr auto name = #NAME;                           \
-        template <typename T, typename U>                             \
-        static void execute(const T* src, U* dst, UInt8& null_flag) { \
-            null_flag = src[0] <= 0;                                  \
-            dst[0] = static_cast<U>(FUNC((double)src[0]));            \
-        }                                                             \
-    };                                                                \
-    using Function##CLASS = FunctionMathUnaryToNullType<CLASS##Impl>;
-
-LOG_FUNCTION_IMPL(Log10, log10, std::log10);
-LOG_FUNCTION_IMPL(Log2, log2, std::log2);
-LOG_FUNCTION_IMPL(Ln, ln, std::log);
+using FunctionExp = FunctionMathUnary<UnaryFunctionPlain<ExpName, std::exp>>;
 
 struct LogName {
     static constexpr auto name = "log";
@@ -224,22 +207,22 @@ using FunctionPositive = 
FunctionUnaryArithmetic<PositiveImpl, NamePositive, fal
 struct SinName {
     static constexpr auto name = "sin";
 };
-using FunctionSin = FunctionMathUnary<UnaryFunctionVectorized<SinName, 
std::sin>>;
+using FunctionSin = FunctionMathUnary<UnaryFunctionPlain<SinName, std::sin>>;
 
 struct SqrtName {
     static constexpr auto name = "sqrt";
 };
-using FunctionSqrt = FunctionMathUnary<UnaryFunctionVectorized<SqrtName, 
std::sqrt>>;
+using FunctionSqrt = FunctionMathUnary<UnaryFunctionPlain<SqrtName, 
std::sqrt>>;
 
 struct CbrtName {
     static constexpr auto name = "cbrt";
 };
-using FunctionCbrt = FunctionMathUnary<UnaryFunctionVectorized<CbrtName, 
std::cbrt>>;
+using FunctionCbrt = FunctionMathUnary<UnaryFunctionPlain<CbrtName, 
std::cbrt>>;
 
 struct TanName {
     static constexpr auto name = "tan";
 };
-using FunctionTan = FunctionMathUnary<UnaryFunctionVectorized<TanName, 
std::tan>>;
+using FunctionTan = FunctionMathUnary<UnaryFunctionPlain<TanName, std::tan>>;
 
 template <typename A>
 struct RadiansImpl {
@@ -408,11 +391,11 @@ void register_function_math(SimpleFunctionFactory& 
factory) {
     factory.register_alias("ceil", "dceil");
     factory.register_alias("ceil", "ceiling");
     factory.register_function<FunctionE>();
-    factory.register_function<FunctionLn>();
     factory.register_alias("ln", "dlog1");
     factory.register_function<FunctionLog>();
-    factory.register_function<FunctionLog2>();
-    factory.register_function<FunctionLog10>();
+    factory.register_function<FunctionMathLog<ImplLn>>();
+    factory.register_function<FunctionMathLog<ImplLog2>>();
+    factory.register_function<FunctionMathLog<ImplLog10>>();
     factory.register_alias("log10", "dlog10");
     factory.register_function<FunctionPi>();
     factory.register_function<FunctionSign>();
diff --git a/be/test/vec/utils/arrow_column_to_doris_column_test.cpp 
b/be/test/vec/utils/arrow_column_to_doris_column_test.cpp
index ad9db66c813..58ae47f75ba 100644
--- a/be/test/vec/utils/arrow_column_to_doris_column_test.cpp
+++ b/be/test/vec/utils/arrow_column_to_doris_column_test.cpp
@@ -401,41 +401,6 @@ void 
test_arrow_to_decimal_column(std::shared_ptr<arrow::Decimal128Type> type,
     }
 }
 
-template <bool is_nullable>
-void test_decimalv2(std::shared_ptr<arrow::Decimal128Type> type,
-                    const std::vector<std::string>& test_cases, size_t 
num_elements) {
-    size_t counter = 0;
-    auto pt = arrow_type_to_primitive_type(type->id());
-    ASSERT_NE(pt, INVALID_TYPE);
-    DataTypePtr data_type = DataTypeFactory::instance().create_data_type(pt, 
true);
-    MutableColumnPtr data_column = data_type->create_column();
-    ColumnWithTypeAndName column(std::move(data_column), data_type, 
"test_numeric_column");
-    auto max_result =
-            
vectorized::DataTypeDecimal<vectorized::Decimal128>::get_max_digits_number(27);
-    auto min_result = -max_result;
-    for (auto& str : test_cases) {
-        int128_t value = DecimalV2Value(str).value();
-        int128_t expect_value =
-                
convert_decimals<vectorized::DataTypeDecimal<vectorized::Decimal128>,
-                                 
vectorized::DataTypeDecimal<vectorized::Decimal128>, true, true>(
-                        value, type->scale(), 9, min_result, max_result);
-        test_arrow_to_decimal_column<is_nullable>(type, column, num_elements, 
value, expect_value,
-                                                  counter);
-    }
-}
-
-TEST(ArrowColumnToDorisColumnTest, test_decimalv2) {
-    std::vector<std::string> test_cases = {"1.2345678", "-12.34567890", 
"99999999999.99999999",
-                                           "-99999999999.99999999"};
-    auto type_p27s9 = std::make_shared<arrow::Decimal128Type>(27, 9);
-    test_decimalv2<false>(type_p27s9, test_cases, 64);
-    test_decimalv2<true>(type_p27s9, test_cases, 64);
-
-    auto type_p27s25 = std::make_shared<arrow::Decimal128Type>(27, 25);
-    test_decimalv2<false>(type_p27s25, test_cases, 128);
-    test_decimalv2<true>(type_p27s25, test_cases, 128);
-}
-
 template <int bytes_width, bool is_nullable = false>
 std::shared_ptr<arrow::Array> create_fixed_size_binary_array(int64_t 
num_elements,
                                                              const 
std::string& value,
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java 
b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
index 52d7c934d97..27b8a02a2c1 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
@@ -956,7 +956,7 @@ public class SessionVariable implements Serializable, 
Writable {
     @VariableMgr.VarAttr(name = ENABLE_PROJECTION)
     private boolean enableProjection = true;
 
-    @VariableMgr.VarAttr(name = CHECK_OVERFLOW_FOR_DECIMAL, varType = 
VariableAnnotation.DEPRECATED)
+    @VariableMgr.VarAttr(name = CHECK_OVERFLOW_FOR_DECIMAL)
     private boolean checkOverflowForDecimal = true;
 
     @VariableMgr.VarAttr(name = DECIMAL_OVERFLOW_SCALE, needForward = true, 
description = {
diff --git 
a/regression-test/suites/datatype_p0/decimalv3/test_decimalv3_cast2.groovy 
b/regression-test/suites/datatype_p0/decimalv3/test_decimalv3_cast2.groovy
index ad2fea7240d..a148b0c01e2 100644
--- a/regression-test/suites/datatype_p0/decimalv3/test_decimalv3_cast2.groovy
+++ b/regression-test/suites/datatype_p0/decimalv3/test_decimalv3_cast2.groovy
@@ -974,7 +974,7 @@ suite("test_decimalv3_cast2") {
         sql """
             select cast(k2 as decimalv3(9,1)) from test_float_to_decimal32_1;
         """
-        exception "Arithmetic overflow"
+        exception "overflow"
     }
     qt_castfloat_to_decimal32_1 """
         select cast(k2 as decimalv3(9,0)) from test_float_to_decimal32_1;
@@ -992,7 +992,7 @@ suite("test_decimalv3_cast2") {
         sql """
             select cast(k2 as decimalv3(38,30)) from test_float_to_decimal32_1;
         """
-        exception "Arithmetic overflow"
+        exception "overflow"
     }
     qt_castfloat_to_decimal32_5 """
         select cast(k2 as decimalv3(38,29)) from test_float_to_decimal32_1;
@@ -1005,7 +1005,7 @@ suite("test_decimalv3_cast2") {
         sql """
             select cast(k2 as decimalv3(76,68)) from test_float_to_decimal32_1;
         """
-        exception "Arithmetic overflow"
+        exception "overflow"
     }
     /*
     float numbers i not accurate:
@@ -1046,7 +1046,7 @@ suite("test_decimalv3_cast2") {
         sql """
             select cast(k2 as decimalv3(9,1)) from test_float_to_decimal32_1;
         """
-        exception "Arithmetic overflow"
+        exception "overflow"
     }
     qt_cast_negative_float_to_decimal32_1 """
         select cast(k2 as decimalv3(9,0)) from test_float_to_decimal32_1;
@@ -1064,7 +1064,7 @@ suite("test_decimalv3_cast2") {
         sql """
             select cast(k2 as decimalv3(38,30)) from test_float_to_decimal32_1;
         """
-        exception "Arithmetic overflow"
+        exception "overflow"
     }
     qt_cast_negative_float_to_decimal32_5 """
         select cast(k2 as decimalv3(38,29)) from test_float_to_decimal32_1;
@@ -1077,7 +1077,7 @@ suite("test_decimalv3_cast2") {
         sql """
             select cast(k2 as decimalv3(76,68)) from test_float_to_decimal32_1;
         """
-        exception "Arithmetic overflow"
+        exception "overflow"
     }
     /*
     qt_cast_negative_float_to_decimal32_7 """
diff --git a/regression-test/suites/mv_p0/ssb/q_4_1_r1/q_4_1_r1.groovy 
b/regression-test/suites/mv_p0/ssb/q_4_1_r1/q_4_1_r1.groovy
index 43fa7bc7bcc..56c1a97b2a7 100644
--- a/regression-test/suites/mv_p0/ssb/q_4_1_r1/q_4_1_r1.groovy
+++ b/regression-test/suites/mv_p0/ssb/q_4_1_r1/q_4_1_r1.groovy
@@ -100,7 +100,7 @@ suite ("q_4_1_r1") {
 
     sql """INSERT INTO lineorder_flat (LO_ORDERDATE, LO_ORDERKEY, 
LO_LINENUMBER, LO_CUSTKEY, LO_PARTKEY, LO_SUPPKEY, LO_ORDERPRIORITY, 
LO_SHIPPRIORITY, LO_QUANTITY, LO_EXTENDEDPRICE, LO_ORDTOTALPRICE, LO_DISCOUNT, 
LO_REVENUE, LO_SUPPLYCOST, LO_TAX, LO_COMMITDATE, LO_SHIPMODE, C_NAME, 
C_ADDRESS, C_CITY, C_NATION, C_REGION, C_PHONE, C_MKTSEGMENT, S_NAME, 
S_ADDRESS, S_CITY, S_NATION, S_REGION, S_PHONE, P_NAME, P_MFGR, P_CATEGORY, 
P_BRAND, P_COLOR,P_TYPE,P_SIZE,P_CONTAINER) VALUES (1 , 1 , 1 [...]
 
-    qt_select_star "select * from lineorder_flat order by 1,2;"
+    qt_select_star "select * from lineorder_flat order by 1,2,P_MFGR;"
     
     explain {
         sql("""SELECT (LO_ORDERDATE DIV 10000) AS YEAR,


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to