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

morningman pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-2.1 by this push:
     new 8e06f4ad34b [improvement](decimal) improve overflow error message 
(#34689) (#36078)
8e06f4ad34b is described below

commit 8e06f4ad34b33990fa6d4502e0d0a59b296778ab
Author: Mingyu Chen <morning...@163.com>
AuthorDate: Sun Jun 9 20:29:38 2024 +0800

    [improvement](decimal) improve overflow error message (#34689) (#36078)
    
    bp #34689
    
    Co-authored-by: TengJianPing <18241664+jackte...@users.noreply.github.com>
---
 be/src/vec/data_types/data_type_date.h            |   6 +
 be/src/vec/data_types/data_type_date_time.cpp     |   8 ++
 be/src/vec/data_types/data_type_date_time.h       |   1 +
 be/src/vec/data_types/data_type_decimal.cpp       |   5 +
 be/src/vec/data_types/data_type_decimal.h         | 131 +++++++++---------
 be/src/vec/data_types/data_type_ipv4.cpp          |   5 +
 be/src/vec/data_types/data_type_ipv4.h            |   1 +
 be/src/vec/data_types/data_type_ipv6.cpp          |   4 +
 be/src/vec/data_types/data_type_ipv6.h            |   1 +
 be/src/vec/data_types/data_type_number_base.cpp   |  13 ++
 be/src/vec/data_types/data_type_number_base.h     |   1 +
 be/src/vec/data_types/data_type_time.cpp          |   6 +
 be/src/vec/data_types/data_type_time.h            |   2 +
 be/src/vec/data_types/data_type_time_v2.cpp       |  17 +++
 be/src/vec/data_types/data_type_time_v2.h         |   2 +
 be/src/vec/functions/function_binary_arithmetic.h | 156 +++++++++++++++-------
 be/src/vec/functions/function_cast.h              |  10 +-
 be/src/vec/functions/multiply.cpp                 |  10 +-
 18 files changed, 264 insertions(+), 115 deletions(-)

diff --git a/be/src/vec/data_types/data_type_date.h 
b/be/src/vec/data_types/data_type_date.h
index 1ae78678bdc..56f74124d90 100644
--- a/be/src/vec/data_types/data_type_date.h
+++ b/be/src/vec/data_types/data_type_date.h
@@ -60,6 +60,12 @@ public:
     bool equals(const IDataType& rhs) const override;
     std::string to_string(const IColumn& column, size_t row_num) const 
override;
     void to_string(const IColumn& column, size_t row_num, BufferWritable& 
ostr) const override;
+    std::string to_string(Int64 int_val) const {
+        doris::VecDateTimeValue value = binary_cast<Int64, 
doris::VecDateTimeValue>(int_val);
+        char buf[64];
+        value.to_string(buf);
+        return buf;
+    }
     Status from_string(ReadBuffer& rb, IColumn* column) const override;
 
     static void cast_to_date(Int64& x);
diff --git a/be/src/vec/data_types/data_type_date_time.cpp 
b/be/src/vec/data_types/data_type_date_time.cpp
index 7985e4728c0..857251cd095 100644
--- a/be/src/vec/data_types/data_type_date_time.cpp
+++ b/be/src/vec/data_types/data_type_date_time.cpp
@@ -56,6 +56,14 @@ std::string DataTypeDateTime::to_string(const IColumn& 
column, size_t row_num) c
     return buf;
 }
 
+std::string DataTypeDateTime::to_string(Int64 int_val) const {
+    doris::VecDateTimeValue value = binary_cast<Int64, 
doris::VecDateTimeValue>(int_val);
+
+    char buf[64];
+    value.to_string(buf);
+    // DateTime to_string the end is /0
+    return buf;
+}
 void DataTypeDateTime::to_string(const IColumn& column, size_t row_num,
                                  BufferWritable& ostr) const {
     auto result = check_column_const_set_readability(column, row_num);
diff --git a/be/src/vec/data_types/data_type_date_time.h 
b/be/src/vec/data_types/data_type_date_time.h
index 5633449bc43..3f604a541c1 100644
--- a/be/src/vec/data_types/data_type_date_time.h
+++ b/be/src/vec/data_types/data_type_date_time.h
@@ -84,6 +84,7 @@ public:
     bool equals(const IDataType& rhs) const override;
 
     std::string to_string(const IColumn& column, size_t row_num) const 
override;
+    std::string to_string(Int64 value) const;
 
     DataTypeSerDeSPtr get_serde(int nesting_level = 1) const override {
         return std::make_shared<DataTypeDateTimeSerDe>(nesting_level);
diff --git a/be/src/vec/data_types/data_type_decimal.cpp 
b/be/src/vec/data_types/data_type_decimal.cpp
index 6532a5f0b7a..e316903fe86 100644
--- a/be/src/vec/data_types/data_type_decimal.cpp
+++ b/be/src/vec/data_types/data_type_decimal.cpp
@@ -91,6 +91,11 @@ void DataTypeDecimal<T>::to_string(const IColumn& column, 
size_t row_num,
     }
 }
 
+template <typename T>
+std::string DataTypeDecimal<T>::to_string(const T& value) const {
+    return value.to_string(scale);
+}
+
 template <typename T>
 Status DataTypeDecimal<T>::from_string(ReadBuffer& rb, IColumn* column) const {
     auto& column_data = static_cast<ColumnType&>(*column).get_data();
diff --git a/be/src/vec/data_types/data_type_decimal.h 
b/be/src/vec/data_types/data_type_decimal.h
index a2f4170f236..8b12010e159 100644
--- a/be/src/vec/data_types/data_type_decimal.h
+++ b/be/src/vec/data_types/data_type_decimal.h
@@ -253,6 +253,7 @@ public:
 
     std::string to_string(const IColumn& column, size_t row_num) const 
override;
     void to_string(const IColumn& column, size_t row_num, BufferWritable& 
ostr) const override;
+    std::string to_string(const T& value) const;
     Status from_string(ReadBuffer& rb, IColumn* column) const override;
     DataTypeSerDeSPtr get_serde(int nesting_level = 1) const override {
         return std::make_shared<DataTypeDecimalSerDe<T>>(scale, precision, 
nesting_level);
@@ -436,12 +437,16 @@ template <typename DataType>
 constexpr bool IsDataTypeDecimalOrNumber =
         IsDataTypeDecimal<DataType> || IsDataTypeNumber<DataType>;
 
+#define THROW_DECIMAL_CONVERT_OVERFLOW_EXCEPTION(value, from_type_name, 
to_type_name)              \
+    throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,                     
                    \
+                    "Arithmetic overflow when converting value {} from type {} 
to type {}", value, \
+                    from_type_name, to_type_name)
 // 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>
+template <typename FromDataType, typename OrigFromDataType, typename 
ToDataType,
+          bool multiply_may_overflow, bool narrow_integral, typename RealFrom, 
typename RealTo>
     requires IsDataTypeDecimal<FromDataType> && IsDataTypeDecimal<ToDataType>
-void convert_to_decimals(RealTo* dst, const RealFrom* src, UInt32 scale_from, 
UInt32 scale_to,
-                         const typename ToDataType::FieldType& min_result,
+void convert_to_decimals(RealTo* dst, const RealFrom* src, UInt32 scale_from, 
UInt32 precicion_to,
+                         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;
@@ -453,18 +458,21 @@ void convert_to_decimals(RealTo* dst, const RealFrom* 
src, UInt32 scale_from, UI
     MaxFieldType multiplier =
             DataTypeDecimal<MaxFieldType>::get_scale_multiplier(scale_to - 
scale_from);
     MaxFieldType tmp;
+    ToDataType to_data_type(precicion_to, scale_to);
+    auto from_type_name = OrigFromDataType {}.get_name();
     for (size_t i = 0; i < size; i++) {
         if constexpr (multiply_may_overflow) {
             if (common::mul_overflow(static_cast<MaxFieldType>(src[i]).value, 
multiplier.value,
                                      tmp.value)) {
-                throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR, 
"Arithmetic overflow");
+                auto value_str = OrigFromDataType {}.to_string(src[i]);
+                THROW_DECIMAL_CONVERT_OVERFLOW_EXCEPTION(value_str, 
from_type_name,
+                                                         
to_data_type.get_name());
             }
             if constexpr (narrow_integral) {
                 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);
+                    auto value_str = OrigFromDataType {}.to_string(src[i]);
+                    THROW_DECIMAL_CONVERT_OVERFLOW_EXCEPTION(value_str, 
from_type_name,
+                                                             
to_data_type.get_name());
                 }
             }
             dst[i].value = tmp.value;
@@ -476,21 +484,20 @@ void convert_to_decimals(RealTo* dst, const RealFrom* 
src, UInt32 scale_from, UI
     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);
+                auto value_str = OrigFromDataType {}.to_string(src[i]);
+                THROW_DECIMAL_CONVERT_OVERFLOW_EXCEPTION(value_str, 
from_type_name,
+                                                         
to_data_type.get_name());
             }
         }
     }
 }
 
 // only for casting between other integral types and decimals
-template <typename FromDataType, typename ToDataType, bool narrow_integral, 
typename RealFrom,
-          typename RealTo>
+template <typename FromDataType, typename ToDataType, typename OrigToDataType, 
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,
+void convert_from_decimals(RealTo* dst, const RealFrom* src, UInt32 
precicion_from,
+                           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;
@@ -499,20 +506,21 @@ void convert_from_decimals(RealTo* dst, const RealFrom* 
src, UInt32 scale_from,
 
     // from decimal to integer
     MaxFieldType multiplier = 
DataTypeDecimal<MaxFieldType>::get_scale_multiplier(scale_from);
+    FromDataType from_data_type(precicion_from, 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);
+                
THROW_DECIMAL_CONVERT_OVERFLOW_EXCEPTION(from_data_type.to_string(src[i]),
+                                                         
from_data_type.get_name(),
+                                                         OrigToDataType 
{}.get_name());
             }
         }
         dst[i] = tmp;
     }
 }
 
+// convert between decimal types
 template <typename FromDataType, typename ToDataType, bool 
multiply_may_overflow,
           bool narrow_integral>
 void convert_decimal_cols(
@@ -532,6 +540,8 @@ void convert_decimal_cols(
                                                   FromFieldType, ToFieldType>>;
     using MaxNativeType = typename MaxFieldType::NativeType;
 
+    FromDataType from_data_type(precision_from, scale_from);
+    ToDataType to_data_type(precision_to, scale_to);
     auto max_result = 
DataTypeDecimal<ToFieldType>::get_max_digits_number(precision_to);
     if (scale_to > scale_from) {
         const MaxNativeType multiplier =
@@ -541,13 +551,14 @@ void convert_decimal_cols(
             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");
+                    
THROW_DECIMAL_CONVERT_OVERFLOW_EXCEPTION(from_data_type.to_string(vec_from[i]),
+                                                             
from_data_type.get_name(),
+                                                             
to_data_type.get_name());
                 } 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);
+                        THROW_DECIMAL_CONVERT_OVERFLOW_EXCEPTION(
+                                from_data_type.to_string(vec_from[i]), 
from_data_type.get_name(),
+                                to_data_type.get_name());
                     } else {
                         vec_to[i] = ToFieldType(res);
                     }
@@ -556,10 +567,9 @@ void convert_decimal_cols(
                 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);
+                        THROW_DECIMAL_CONVERT_OVERFLOW_EXCEPTION(
+                                from_data_type.to_string(vec_from[i]), 
from_data_type.get_name(),
+                                to_data_type.get_name());
                     }
                 }
                 vec_to[i] = ToFieldType(res);
@@ -570,10 +580,9 @@ void convert_decimal_cols(
             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);
+                    
THROW_DECIMAL_CONVERT_OVERFLOW_EXCEPTION(from_data_type.to_string(vec_from[i]),
+                                                             
from_data_type.get_name(),
+                                                             
to_data_type.get_name());
                 }
             }
             vec_to[i] = ToFieldType(vec_from[i].value);
@@ -587,10 +596,9 @@ void convert_decimal_cols(
                 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);
+                        THROW_DECIMAL_CONVERT_OVERFLOW_EXCEPTION(
+                                from_data_type.to_string(vec_from[i]), 
from_data_type.get_name(),
+                                to_data_type.get_name());
                     }
                     vec_to[i] = ToFieldType(res);
                 } else {
@@ -600,10 +608,9 @@ void convert_decimal_cols(
                 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);
+                        THROW_DECIMAL_CONVERT_OVERFLOW_EXCEPTION(
+                                from_data_type.to_string(vec_from[i]), 
from_data_type.get_name(),
+                                to_data_type.get_name());
                     }
                     vec_to[i] = ToFieldType(res);
                 } else {
@@ -614,11 +621,12 @@ void convert_decimal_cols(
     }
 }
 
+// convert from decimal to non-decimal
 template <typename FromDataType, typename ToDataType, bool narrow_integral>
-    requires IsDataTypeDecimal<FromDataType>
+    requires IsDataTypeDecimal<FromDataType> && 
(!IsDataTypeDecimal<ToDataType>)
 void convert_from_decimal(typename ToDataType::FieldType* dst,
-                          const typename FromDataType::FieldType* src, UInt32 
scale,
-                          const typename ToDataType::FieldType& min_result,
+                          const typename FromDataType::FieldType* src, UInt32 
precision,
+                          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;
@@ -634,28 +642,31 @@ void convert_from_decimal(typename ToDataType::FieldType* 
dst,
                 dst[i] = static_cast<ToFieldType>(src[i].value) / 
multiplier.value;
             }
         }
+        FromDataType from_data_type(precision, scale);
         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);
+                    
THROW_DECIMAL_CONVERT_OVERFLOW_EXCEPTION(from_data_type.to_string(src[i]),
+                                                             
from_data_type.get_name(),
+                                                             ToDataType 
{}.get_name());
                 }
             }
         }
     } else {
-        convert_from_decimals<FromDataType, FromDataType, narrow_integral>(
-                dst, src, scale, FromFieldType(min_result), 
FromFieldType(max_result), size);
+        convert_from_decimals<FromDataType, FromDataType, ToDataType, 
narrow_integral>(
+                dst, src, precision, scale, FromFieldType(min_result), 
FromFieldType(max_result),
+                size);
     }
 }
 
+// convert from non-decimal to decimal
 template <typename FromDataType, typename ToDataType, bool 
multiply_may_overflow,
           bool narrow_integral>
     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,
+                        UInt32 to_precision, UInt32 to_scale,
+                        const typename ToDataType::FieldType& min_result,
                         const typename ToDataType::FieldType& max_result, 
size_t size) {
     using FromFieldType = typename FromDataType::FieldType;
 
@@ -670,11 +681,11 @@ void convert_to_decimal(typename ToDataType::FieldType* 
dst,
                 }
                 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));
+                    ToDataType to_data_type(to_precision, to_scale);
+                    throw Exception(
+                            ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
+                            "Arithmetic overflow when converting value {} from 
type {} to type {}",
+                            src[i], FromDataType {}.get_name(), 
to_data_type.get_name());
                 }
             }
         }
@@ -687,9 +698,9 @@ void convert_to_decimal(typename ToDataType::FieldType* dst,
                 std::conditional_t<std::is_same_v<FromFieldType, Int128>, 
Decimal128V2,
                                    
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);
+        convert_to_decimals<DataTypeDecimal<DecimalFrom>, FromDataType, 
ToDataType,
+                            multiply_may_overflow, narrow_integral>(
+                dst, src, from_scale, to_precision, to_scale, min_result, 
max_result, size);
     }
 }
 
diff --git a/be/src/vec/data_types/data_type_ipv4.cpp 
b/be/src/vec/data_types/data_type_ipv4.cpp
index f7aaca5c73e..5b7c43af874 100644
--- a/be/src/vec/data_types/data_type_ipv4.cpp
+++ b/be/src/vec/data_types/data_type_ipv4.cpp
@@ -41,6 +41,11 @@ std::string DataTypeIPv4::to_string(const IColumn& column, 
size_t row_num) const
     return value.to_string();
 }
 
+std::string DataTypeIPv4::to_string(const IPv4& ipv4_val) const {
+    auto value = IPv4Value(ipv4_val);
+    return value.to_string();
+}
+
 void DataTypeIPv4::to_string(const IColumn& column, size_t row_num, 
BufferWritable& ostr) const {
     std::string value = to_string(column, row_num);
     ostr.write(value.data(), value.size());
diff --git a/be/src/vec/data_types/data_type_ipv4.h 
b/be/src/vec/data_types/data_type_ipv4.h
index 8874d8010ff..5d72d7a04e4 100644
--- a/be/src/vec/data_types/data_type_ipv4.h
+++ b/be/src/vec/data_types/data_type_ipv4.h
@@ -58,6 +58,7 @@ public:
     bool equals(const IDataType& rhs) const override;
     std::string to_string(const IColumn& column, size_t row_num) const 
override;
     void to_string(const IColumn& column, size_t row_num, BufferWritable& 
ostr) const override;
+    std::string to_string(const IPv4& value) const;
     Status from_string(ReadBuffer& rb, IColumn* column) const override;
 
     Field get_field(const TExprNode& node) const override { return 
(IPv4)node.ipv4_literal.value; }
diff --git a/be/src/vec/data_types/data_type_ipv6.cpp 
b/be/src/vec/data_types/data_type_ipv6.cpp
index 78b8e8e07d7..11b8d250071 100755
--- a/be/src/vec/data_types/data_type_ipv6.cpp
+++ b/be/src/vec/data_types/data_type_ipv6.cpp
@@ -42,6 +42,10 @@ std::string DataTypeIPv6::to_string(const IColumn& column, 
size_t row_num) const
     return value.to_string();
 }
 
+std::string DataTypeIPv6::to_string(const IPv6& ipv6_val) const {
+    auto value = IPv6Value(ipv6_val);
+    return value.to_string();
+}
 void DataTypeIPv6::to_string(const IColumn& column, size_t row_num, 
BufferWritable& ostr) const {
     std::string value = to_string(column, row_num);
     ostr.write(value.data(), value.size());
diff --git a/be/src/vec/data_types/data_type_ipv6.h 
b/be/src/vec/data_types/data_type_ipv6.h
index d43fc2d3340..34c97c4a1e9 100755
--- a/be/src/vec/data_types/data_type_ipv6.h
+++ b/be/src/vec/data_types/data_type_ipv6.h
@@ -57,6 +57,7 @@ public:
     bool equals(const IDataType& rhs) const override;
     std::string to_string(const IColumn& column, size_t row_num) const 
override;
     void to_string(const IColumn& column, size_t row_num, BufferWritable& 
ostr) const override;
+    std::string to_string(const IPv6& value) const;
     Status from_string(ReadBuffer& rb, IColumn* column) const override;
 
     Field get_field(const TExprNode& node) const override {
diff --git a/be/src/vec/data_types/data_type_number_base.cpp 
b/be/src/vec/data_types/data_type_number_base.cpp
index 29032915999..78d6e81fb58 100644
--- a/be/src/vec/data_types/data_type_number_base.cpp
+++ b/be/src/vec/data_types/data_type_number_base.cpp
@@ -65,6 +65,19 @@ void DataTypeNumberBase<T>::to_string(const IColumn& column, 
size_t row_num,
     }
 }
 
+template <typename T>
+std::string DataTypeNumberBase<T>::to_string(const T& value) const {
+    if constexpr (std::is_same<T, int128_t>::value || std::is_same<T, 
uint128_t>::value ||
+                  std::is_same<T, UInt128>::value) {
+        return int128_to_string(value);
+    } else if constexpr (std::is_integral<T>::value) {
+        return std::to_string(value);
+    } else if constexpr (std::numeric_limits<T>::is_iec559) {
+        fmt::memory_buffer buffer; // only use in size-predictable type.
+        fmt::format_to(buffer, "{}", value);
+        return std::string(buffer.data(), buffer.size());
+    }
+}
 template <typename T>
 Status DataTypeNumberBase<T>::from_string(ReadBuffer& rb, IColumn* column) 
const {
     auto* column_data = static_cast<ColumnVector<T>*>(column);
diff --git a/be/src/vec/data_types/data_type_number_base.h 
b/be/src/vec/data_types/data_type_number_base.h
index 4ec30a3ef94..bc173520fa0 100644
--- a/be/src/vec/data_types/data_type_number_base.h
+++ b/be/src/vec/data_types/data_type_number_base.h
@@ -156,6 +156,7 @@ public:
 
     void to_string(const IColumn& column, size_t row_num, BufferWritable& 
ostr) const override;
     std::string to_string(const IColumn& column, size_t row_num) const 
override;
+    std::string to_string(const T& value) const;
     Status from_string(ReadBuffer& rb, IColumn* column) const override;
     bool is_null_literal() const override { return _is_null_literal; }
     void set_null_literal(bool flag) { _is_null_literal = flag; }
diff --git a/be/src/vec/data_types/data_type_time.cpp 
b/be/src/vec/data_types/data_type_time.cpp
index d9c2af440e9..4ed0e37da11 100644
--- a/be/src/vec/data_types/data_type_time.cpp
+++ b/be/src/vec/data_types/data_type_time.cpp
@@ -53,6 +53,9 @@ std::string DataTypeTime::to_string(const IColumn& column, 
size_t row_num) const
     return time_to_buffer_from_double(value);
 }
 
+std::string DataTypeTime::to_string(double value) const {
+    return time_to_buffer_from_double(value);
+}
 void DataTypeTime::to_string(const IColumn& column, size_t row_num, 
BufferWritable& ostr) const {
     std::string value = to_string(column, row_num);
     ostr.write(value.data(), value.size());
@@ -80,6 +83,9 @@ std::string DataTypeTimeV2::to_string(const IColumn& column, 
size_t row_num) con
     return timev2_to_buffer_from_double(value, _scale);
 }
 
+std::string DataTypeTimeV2::to_string(double value) const {
+    return timev2_to_buffer_from_double(value, _scale);
+}
 void DataTypeTimeV2::to_string(const IColumn& column, size_t row_num, 
BufferWritable& ostr) const {
     std::string value = to_string(column, row_num);
     ostr.write(value.data(), value.size());
diff --git a/be/src/vec/data_types/data_type_time.h 
b/be/src/vec/data_types/data_type_time.h
index 27b1f931bce..c7f5068b9f4 100644
--- a/be/src/vec/data_types/data_type_time.h
+++ b/be/src/vec/data_types/data_type_time.h
@@ -53,6 +53,7 @@ public:
     bool equals(const IDataType& rhs) const override;
 
     std::string to_string(const IColumn& column, size_t row_num) const 
override;
+    std::string to_string(double int_val) const;
     TypeDescriptor get_type_as_type_descriptor() const override {
         return TypeDescriptor(TYPE_TIME);
     }
@@ -85,6 +86,7 @@ public:
     bool equals(const IDataType& rhs) const override;
 
     std::string to_string(const IColumn& column, size_t row_num) const 
override;
+    std::string to_string(double int_val) const;
     TypeDescriptor get_type_as_type_descriptor() const override {
         return TypeDescriptor(TYPE_TIMEV2);
     }
diff --git a/be/src/vec/data_types/data_type_time_v2.cpp 
b/be/src/vec/data_types/data_type_time_v2.cpp
index c92201ee08d..bdd2dcf8612 100644
--- a/be/src/vec/data_types/data_type_time_v2.cpp
+++ b/be/src/vec/data_types/data_type_time_v2.cpp
@@ -60,6 +60,14 @@ std::string DataTypeDateV2::to_string(const IColumn& column, 
size_t row_num) con
     return std::string {buf};
 }
 
+std::string DataTypeDateV2::to_string(UInt32 int_val) const {
+    DateV2Value<DateV2ValueType> val = binary_cast<UInt32, 
DateV2Value<DateV2ValueType>>(int_val);
+
+    char buf[64];
+    val.to_string(buf); // DateTime to_string the end is /0
+    return std::string {buf};
+}
+
 void DataTypeDateV2::to_string(const IColumn& column, size_t row_num, 
BufferWritable& ostr) const {
     auto result = check_column_const_set_readability(column, row_num);
     ColumnPtr ptr = result.first;
@@ -135,6 +143,15 @@ std::string DataTypeDateTimeV2::to_string(const IColumn& 
column, size_t row_num)
     return buf; // DateTime to_string the end is /0
 }
 
+std::string DataTypeDateTimeV2::to_string(UInt64 int_val) const {
+    DateV2Value<DateTimeV2ValueType> val =
+            binary_cast<UInt64, DateV2Value<DateTimeV2ValueType>>(int_val);
+
+    char buf[64];
+    val.to_string(buf, _scale);
+    return buf; // DateTime to_string the end is /0
+}
+
 void DataTypeDateTimeV2::to_string(const IColumn& column, size_t row_num,
                                    BufferWritable& ostr) const {
     auto result = check_column_const_set_readability(column, row_num);
diff --git a/be/src/vec/data_types/data_type_time_v2.h 
b/be/src/vec/data_types/data_type_time_v2.h
index 6d26a8c0ff1..f15a06303c6 100644
--- a/be/src/vec/data_types/data_type_time_v2.h
+++ b/be/src/vec/data_types/data_type_time_v2.h
@@ -83,6 +83,7 @@ public:
     bool equals(const IDataType& rhs) const override;
     std::string to_string(const IColumn& column, size_t row_num) const 
override;
     void to_string(const IColumn& column, size_t row_num, BufferWritable& 
ostr) const override;
+    std::string to_string(UInt32 int_val) const;
     Status from_string(ReadBuffer& rb, IColumn* column) const override;
 
     MutableColumnPtr create_column() const override;
@@ -125,6 +126,7 @@ public:
     bool equals(const IDataType& rhs) const override;
     std::string to_string(const IColumn& column, size_t row_num) const 
override;
     void to_string(const IColumn& column, size_t row_num, BufferWritable& 
ostr) const override;
+    std::string to_string(UInt64 int_val) const;
     Status from_string(ReadBuffer& rb, IColumn* column) const override;
     DataTypeSerDeSPtr get_serde(int nesting_level = 1) const override {
         return std::make_shared<DataTypeDateTimeV2SerDe>(_scale, 
nesting_level);
diff --git a/be/src/vec/functions/function_binary_arithmetic.h 
b/be/src/vec/functions/function_binary_arithmetic.h
index a34709732cc..53d8141bc9e 100644
--- a/be/src/vec/functions/function_binary_arithmetic.h
+++ b/be/src/vec/functions/function_binary_arithmetic.h
@@ -220,12 +220,17 @@ struct BinaryOperationImpl {
     }
 };
 
+#define THROW_DECIMAL_BINARY_OP_OVERFLOW_EXCEPTION(left_value, op_name, 
right_value, result_value, \
+                                                   result_type_name)           
                    \
+    throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,                     
                    \
+                    "Arithmetic overflow: {} {} {} = {}, result type: {}", 
left_value, op_name,    \
+                    right_value, result_value, result_type_name)
 /// Binary operations for Decimals need scale args
 /// +|- scale one of args (which scale factor is not 1). ScaleR = 
oneof(Scale1, Scale2);
 /// *   no agrs scale. ScaleR = Scale1 + Scale2;
 /// /   first arg scale. ScaleR = Scale1 (scale_a = 
DecimalType<B>::get_scale()).
-template <typename LeftDataType, typename RightDataType,
-          template <typename, typename> typename Operation, typename 
ResultType,
+template <typename LeftDataType, typename RightDataType, typename 
ResultDataType,
+          template <typename, typename> typename Operation, typename Name, 
typename ResultType,
           bool is_to_null_type, bool check_overflow>
 struct DecimalBinaryOperation {
     using A = typename LeftDataType::FieldType;
@@ -246,8 +251,9 @@ private:
 
     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,
-                              const ResultType& max_result_number,
+                              typename ArrayC::value_type* c, const 
LeftDataType& type_left,
+                              const RightDataType& type_right, const 
ResultDataType& type_result,
+                              size_t size, const ResultType& max_result_number,
                               const ResultType& scale_diff_multiplier) {
         static_assert(OpTraits::is_plus_minus || OpTraits::is_multiply);
         if constexpr (OpTraits::is_multiply && IsDecimalV2<A> && 
IsDecimalV2<B> &&
@@ -259,7 +265,8 @@ private:
                     [&](auto need_adjust_scale) {
                         for (size_t i = 0; i < size; i++) {
                             c[i] = typename 
ArrayC::value_type(apply<need_adjust_scale>(
-                                    a[i], b[i], max_result_number, 
scale_diff_multiplier));
+                                    a[i], b[i], type_left, type_right, 
type_result,
+                                    max_result_number, scale_diff_multiplier));
                         }
                     },
                     make_bool_variant(need_adjust_scale && check_overflow));
@@ -310,8 +317,9 @@ private:
     }
 
     static void vector_constant(const typename Traits::ArrayA::value_type* 
__restrict a, B b,
-                                typename ArrayC::value_type* c, size_t size,
-                                const ResultType& max_result_number,
+                                typename ArrayC::value_type* c, const 
LeftDataType& type_left,
+                                const RightDataType& type_right, const 
ResultDataType& type_result,
+                                size_t size, const ResultType& 
max_result_number,
                                 const ResultType& scale_diff_multiplier) {
         static_assert(!OpTraits::is_division);
 
@@ -320,7 +328,8 @@ private:
                 [&](auto need_adjust_scale) {
                     for (size_t i = 0; i < size; ++i) {
                         c[i] = typename 
ArrayC::value_type(apply<need_adjust_scale>(
-                                a[i], b, max_result_number, 
scale_diff_multiplier));
+                                a[i], b, type_left, type_right, type_result, 
max_result_number,
+                                scale_diff_multiplier));
                     }
                 },
                 make_bool_variant(need_adjust_scale));
@@ -343,15 +352,17 @@ private:
     }
 
     static void constant_vector(A a, const typename 
Traits::ArrayB::value_type* __restrict b,
-                                typename ArrayC::value_type* c, size_t size,
-                                const ResultType& max_result_number,
+                                typename ArrayC::value_type* c, const 
LeftDataType& type_left,
+                                const RightDataType& type_right, const 
ResultDataType& type_result,
+                                size_t size, const ResultType& 
max_result_number,
                                 const ResultType& scale_diff_multiplier) {
         bool need_adjust_scale = scale_diff_multiplier.value > 1;
         std::visit(
                 [&](auto need_adjust_scale) {
                     for (size_t i = 0; i < size; ++i) {
                         c[i] = typename 
ArrayC::value_type(apply<need_adjust_scale>(
-                                a, b[i], max_result_number, 
scale_diff_multiplier));
+                                a, b[i], type_left, type_right, type_result, 
max_result_number,
+                                scale_diff_multiplier));
                     }
                 },
                 make_bool_variant(need_adjust_scale));
@@ -373,9 +384,13 @@ private:
         }
     }
 
-    static ResultType constant_constant(A a, B b, const ResultType& 
max_result_number,
+    static ResultType constant_constant(A a, B b, const LeftDataType& 
type_left,
+                                        const RightDataType& type_right,
+                                        const ResultDataType& type_result,
+                                        const ResultType& max_result_number,
                                         const ResultType& 
scale_diff_multiplier) {
-        return ResultType(apply<true>(a, b, max_result_number, 
scale_diff_multiplier));
+        return ResultType(apply<true>(a, b, type_left, type_right, 
type_result, max_result_number,
+                                      scale_diff_multiplier));
     }
 
     static ResultType constant_constant(A a, B b, UInt8& is_null,
@@ -393,9 +408,12 @@ private:
     }
 
 public:
-    static ColumnPtr adapt_decimal_constant_constant(A a, B b, const 
ResultType& max_result_number,
+    static ColumnPtr adapt_decimal_constant_constant(A a, B b, const 
LeftDataType& type_left,
+                                                     const RightDataType& 
type_right,
+                                                     const ResultType& 
max_result_number,
                                                      const ResultType& 
scale_diff_multiplier,
                                                      DataTypePtr 
res_data_type) {
+        auto type_result = assert_cast<const 
DataTypeDecimal<ResultType>&>(*res_data_type);
         auto column_result = ColumnDecimal<ResultType>::create(
                 1, assert_cast<const 
DataTypeDecimal<ResultType>&>(*res_data_type).get_scale());
 
@@ -410,15 +428,19 @@ public:
             return ColumnNullable::create(std::move(column_result), 
std::move(null_map));
         } else {
             column_result->get_element(0) =
-                    constant_constant(a, b, max_result_number, 
scale_diff_multiplier);
+                    constant_constant(a, b, type_left, type_right, 
type_result, max_result_number,
+                                      scale_diff_multiplier);
             return column_result;
         }
     }
 
     static ColumnPtr adapt_decimal_vector_constant(ColumnPtr column_left, B b,
+                                                   const LeftDataType& 
type_left,
+                                                   const RightDataType& 
type_right,
                                                    const ResultType& 
max_result_number,
                                                    const ResultType& 
scale_diff_multiplier,
                                                    DataTypePtr res_data_type) {
+        auto type_result = assert_cast<const 
DataTypeDecimal<ResultType>&>(*res_data_type);
         auto column_left_ptr = check_and_get_column<typename 
Traits::ColumnVectorA>(column_left);
         auto column_result = ColumnDecimal<ResultType>::create(
                 column_left->size(),
@@ -436,15 +458,19 @@ public:
             return ColumnNullable::create(std::move(column_result), 
std::move(null_map));
         } else {
             vector_constant(column_left_ptr->get_data().data(), b, 
column_result->get_data().data(),
-                            column_left->size(), max_result_number, 
scale_diff_multiplier);
+                            type_left, type_right, type_result, 
column_left->size(),
+                            max_result_number, scale_diff_multiplier);
             return column_result;
         }
     }
 
     static ColumnPtr adapt_decimal_constant_vector(A a, ColumnPtr column_right,
+                                                   const LeftDataType& 
type_left,
+                                                   const RightDataType& 
type_right,
                                                    const ResultType& 
max_result_number,
                                                    const ResultType& 
scale_diff_multiplier,
                                                    DataTypePtr res_data_type) {
+        auto type_result = assert_cast<const 
DataTypeDecimal<ResultType>&>(*res_data_type);
         auto column_right_ptr = check_and_get_column<typename 
Traits::ColumnVectorB>(column_right);
         auto column_result = ColumnDecimal<ResultType>::create(
                 column_right->size(),
@@ -463,13 +489,15 @@ public:
             return ColumnNullable::create(std::move(column_result), 
std::move(null_map));
         } else {
             constant_vector(a, column_right_ptr->get_data().data(),
-                            column_result->get_data().data(), 
column_right->size(),
-                            max_result_number, scale_diff_multiplier);
+                            column_result->get_data().data(), type_left, 
type_right, type_result,
+                            column_right->size(), max_result_number, 
scale_diff_multiplier);
             return column_result;
         }
     }
 
     static ColumnPtr adapt_decimal_vector_vector(ColumnPtr column_left, 
ColumnPtr column_right,
+                                                 const LeftDataType& type_left,
+                                                 const RightDataType& 
type_right,
                                                  const ResultType& 
max_result_number,
                                                  const ResultType& 
scale_diff_multiplier,
                                                  DataTypePtr res_data_type) {
@@ -494,8 +522,8 @@ public:
             return ColumnNullable::create(std::move(column_result), 
std::move(null_map));
         } else {
             vector_vector(column_left_ptr->get_data().data(), 
column_right_ptr->get_data().data(),
-                          column_result->get_data().data(), 
column_left->size(), max_result_number,
-                          scale_diff_multiplier);
+                          column_result->get_data().data(), type_left, 
type_right, type_result,
+                          column_left->size(), max_result_number, 
scale_diff_multiplier);
             return column_result;
         }
     }
@@ -504,6 +532,9 @@ private:
     /// there's implicit type conversion here
     template <bool need_adjust_scale>
     static ALWAYS_INLINE NativeResultType apply(NativeResultType a, 
NativeResultType b,
+                                                const LeftDataType& type_left,
+                                                const RightDataType& 
type_right,
+                                                const ResultDataType& 
type_result,
                                                 const ResultType& 
max_result_number,
                                                 const ResultType& 
scale_diff_multiplier) {
         static_assert(OpTraits::is_plus_minus || OpTraits::is_multiply);
@@ -512,7 +543,10 @@ private:
             if constexpr (check_overflow) {
                 auto res = Op::template apply(DecimalV2Value(a), 
DecimalV2Value(b)).value();
                 if (res > max_result_number.value || res < 
-max_result_number.value) {
-                    throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR, 
"Arithmetic overflow");
+                    THROW_DECIMAL_BINARY_OP_OVERFLOW_EXCEPTION(
+                            DecimalV2Value(a).to_string(), Name::name,
+                            DecimalV2Value(b).to_string(), 
DecimalV2Value(res).to_string(),
+                            ResultDataType {}.get_name());
                 }
                 return res;
             } else {
@@ -524,8 +558,13 @@ private:
                 // TODO handle overflow gracefully
                 if (UNLIKELY(Op::template apply<NativeResultType>(a, b, res))) 
{
                     if constexpr (OpTraits::is_plus_minus) {
-                        throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
-                                        "Arithmetic overflow");
+                        auto result_str =
+                                DataTypeDecimal<Decimal256> 
{BeConsts::MAX_DECIMAL256_PRECISION,
+                                                             
type_result.get_scale()}
+                                        .to_string(Decimal256(res));
+                        THROW_DECIMAL_BINARY_OP_OVERFLOW_EXCEPTION(
+                                type_left.to_string(A(a)), Name::name, 
type_right.to_string(B(b)),
+                                result_str, type_result.get_name());
                     }
                     // multiply
                     if constexpr (std::is_same_v<NativeResultType, __int128>) {
@@ -543,14 +582,24 @@ private:
                         // check if final result is overflow
                         if (res256 > wide::Int256(max_result_number.value) ||
                             res256 < wide::Int256(-max_result_number.value)) {
-                            throw 
Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
-                                            "Arithmetic overflow");
+                            auto result_str =
+                                    DataTypeDecimal<Decimal256> 
{BeConsts::MAX_DECIMAL256_PRECISION,
+                                                                 
type_result.get_scale()}
+                                            .to_string(Decimal256(res256));
+                            THROW_DECIMAL_BINARY_OP_OVERFLOW_EXCEPTION(
+                                    type_left.to_string(A(a)), Name::name,
+                                    type_right.to_string(B(b)), result_str, 
type_result.get_name());
                         } else {
                             res = res256;
                         }
                     } else {
-                        throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
-                                        "Arithmetic overflow");
+                        auto result_str =
+                                DataTypeDecimal<Decimal256> 
{BeConsts::MAX_DECIMAL256_PRECISION,
+                                                             
type_result.get_scale()}
+                                        .to_string(Decimal256(res));
+                        THROW_DECIMAL_BINARY_OP_OVERFLOW_EXCEPTION(
+                                type_left.to_string(A(a)), Name::name, 
type_right.to_string(B(b)),
+                                result_str, type_result.get_name());
                     }
                 } else {
                     // round to final result precision
@@ -564,8 +613,13 @@ private:
                         }
                     }
                     if (res > max_result_number.value || res < 
-max_result_number.value) {
-                        throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
-                                        "Arithmetic overflow");
+                        auto result_str =
+                                DataTypeDecimal<Decimal256> 
{BeConsts::MAX_DECIMAL256_PRECISION,
+                                                             
type_result.get_scale()}
+                                        .to_string(Decimal256(res));
+                        THROW_DECIMAL_BINARY_OP_OVERFLOW_EXCEPTION(
+                                type_left.to_string(A(a)), Name::name, 
type_right.to_string(B(b)),
+                                result_str, type_result.get_name());
                     }
                 }
                 return res;
@@ -597,19 +651,25 @@ private:
                 if constexpr (std::is_same_v<ANS_TYPE, DecimalV2Value>) {
                     if (ans.value() > max_result_number.value ||
                         ans.value() < -max_result_number.value) {
-                        throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
-                                        "Arithmetic overflow");
+                        THROW_DECIMAL_BINARY_OP_OVERFLOW_EXCEPTION(
+                                DecimalV2Value(a).to_string(), Name::name,
+                                DecimalV2Value(b).to_string(), 
DecimalV2Value(ans).to_string(),
+                                ResultDataType {}.get_name());
                     }
                 } else if constexpr (IsDecimalNumber<ANS_TYPE>) {
                     if (ans.value > max_result_number.value ||
                         ans.value < -max_result_number.value) {
-                        throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
-                                        "Arithmetic overflow");
+                        THROW_DECIMAL_BINARY_OP_OVERFLOW_EXCEPTION(
+                                DecimalV2Value(a).to_string(), Name::name,
+                                DecimalV2Value(b).to_string(), 
DecimalV2Value(ans).to_string(),
+                                ResultDataType {}.get_name());
                     }
                 } else {
                     if (ans > max_result_number.value || ans < 
-max_result_number.value) {
-                        throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR,
-                                        "Arithmetic overflow");
+                        THROW_DECIMAL_BINARY_OP_OVERFLOW_EXCEPTION(
+                                DecimalV2Value(a).to_string(), Name::name,
+                                DecimalV2Value(b).to_string(), 
DecimalV2Value(ans).to_string(),
+                                ResultDataType {}.get_name());
                     }
                 }
             }
@@ -714,7 +774,7 @@ struct BinaryOperationTraits {
 };
 
 template <typename LeftDataType, typename RightDataType, typename 
ExpectedResultDataType,
-          template <typename, typename> class Operation, bool is_to_null_type,
+          template <typename, typename> class Operation, typename Name, bool 
is_to_null_type,
           bool check_overflow_for_decimal>
 struct ConstOrVectorAdapter {
     static constexpr bool result_is_decimal =
@@ -727,8 +787,8 @@ struct ConstOrVectorAdapter {
 
     using OperationImpl = std::conditional_t<
             IsDataTypeDecimal<ResultDataType>,
-            DecimalBinaryOperation<LeftDataType, RightDataType, Operation, 
ResultType,
-                                   is_to_null_type, 
check_overflow_for_decimal>,
+            DecimalBinaryOperation<LeftDataType, RightDataType, 
ResultDataType, Operation, Name,
+                                   ResultType, is_to_null_type, 
check_overflow_for_decimal>,
             BinaryOperationImpl<A, B, Operation<A, B>, is_to_null_type, 
ResultType>>;
 
     static ColumnPtr execute(ColumnPtr column_left, ColumnPtr column_right,
@@ -785,8 +845,8 @@ private:
 
             column_result = OperationImpl::adapt_decimal_constant_constant(
                     column_left_ptr->template get_value<A>(),
-                    column_right_ptr->template get_value<B>(), 
max_and_multiplier.first,
-                    max_and_multiplier.second, res_data_type);
+                    column_right_ptr->template get_value<B>(), type_left, 
type_right,
+                    max_and_multiplier.first, max_and_multiplier.second, 
res_data_type);
 
         } else {
             column_result = OperationImpl::adapt_normal_constant_constant(
@@ -808,8 +868,8 @@ private:
                     assert_cast<const 
DataTypeDecimal<ResultType>&>(*res_data_type);
             auto max_and_multiplier = get_max_and_multiplier(type_left, 
type_right, type_result);
             return OperationImpl::adapt_decimal_vector_constant(
-                    column_left->get_ptr(), column_right_ptr->template 
get_value<B>(),
-                    max_and_multiplier.first, max_and_multiplier.second, 
res_data_type);
+                    column_left->get_ptr(), column_right_ptr->template 
get_value<B>(), type_left,
+                    type_right, max_and_multiplier.first, 
max_and_multiplier.second, res_data_type);
         } else {
             return OperationImpl::adapt_normal_vector_constant(
                     column_left->get_ptr(), column_right_ptr->template 
get_value<B>());
@@ -827,8 +887,8 @@ private:
                     assert_cast<const 
DataTypeDecimal<ResultType>&>(*res_data_type);
             auto max_and_multiplier = get_max_and_multiplier(type_left, 
type_right, type_result);
             return OperationImpl::adapt_decimal_constant_vector(
-                    column_left_ptr->template get_value<A>(), 
column_right->get_ptr(),
-                    max_and_multiplier.first, max_and_multiplier.second, 
res_data_type);
+                    column_left_ptr->template get_value<A>(), 
column_right->get_ptr(), type_left,
+                    type_right, max_and_multiplier.first, 
max_and_multiplier.second, res_data_type);
         } else {
             return OperationImpl::adapt_normal_constant_vector(
                     column_left_ptr->template get_value<A>(), 
column_right->get_ptr());
@@ -843,8 +903,8 @@ private:
                     assert_cast<const 
DataTypeDecimal<ResultType>&>(*res_data_type);
             auto max_and_multiplier = get_max_and_multiplier(type_left, 
type_right, type_result);
             return OperationImpl::adapt_decimal_vector_vector(
-                    column_left->get_ptr(), column_right->get_ptr(), 
max_and_multiplier.first,
-                    max_and_multiplier.second, res_data_type);
+                    column_left->get_ptr(), column_right->get_ptr(), 
type_left, type_right,
+                    max_and_multiplier.first, max_and_multiplier.second, 
res_data_type);
         } else {
             return 
OperationImpl::adapt_normal_vector_vector(column_left->get_ptr(),
                                                              
column_right->get_ptr());
@@ -1004,7 +1064,7 @@ public:
                                     LeftDataType, RightDataType,
                                     
std::conditional_t<IsDataTypeDecimal<ExpectedResultDataType>,
                                                        ExpectedResultDataType, 
ResultDataType>,
-                                    Operation, is_to_null_type,
+                                    Operation, Name, is_to_null_type,
                                     
true>::execute(block.get_by_position(arguments[0]).column,
                                                    
block.get_by_position(arguments[1]).column, left,
                                                    right,
@@ -1016,7 +1076,7 @@ public:
                                     LeftDataType, RightDataType,
                                     
std::conditional_t<IsDataTypeDecimal<ExpectedResultDataType>,
                                                        ExpectedResultDataType, 
ResultDataType>,
-                                    Operation, is_to_null_type,
+                                    Operation, Name, is_to_null_type,
                                     
false>::execute(block.get_by_position(arguments[0]).column,
                                                     
block.get_by_position(arguments[1]).column,
                                                     left, right,
diff --git a/be/src/vec/functions/function_cast.h 
b/be/src/vec/functions/function_cast.h
index 7f3f74217b4..952f4f57922 100644
--- a/be/src/vec/functions/function_cast.h
+++ b/be/src/vec/functions/function_cast.h
@@ -346,13 +346,13 @@ struct ConvertImpl {
                                         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);
+                                        vec_to.data(), vec_from.data(), 
from_precision,
+                                        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);
+                                                   narrow_integral>(
+                                        vec_to.data(), vec_from.data(), 
from_scale, to_precision,
+                                        to_scale, min_result, max_result, 
size);
                             }
                         },
                         make_bool_variant(multiply_may_overflow),
diff --git a/be/src/vec/functions/multiply.cpp 
b/be/src/vec/functions/multiply.cpp
index 43da8bb56ff..f871a3a742c 100644
--- a/be/src/vec/functions/multiply.cpp
+++ b/be/src/vec/functions/multiply.cpp
@@ -76,11 +76,17 @@ struct MultiplyImpl {
                 int128_t i128_mul_result;
                 if (common::mul_overflow(DecimalV2Value(a[i]).value(), 
DecimalV2Value(b[i]).value(),
                                          i128_mul_result)) {
-                    throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR, 
"Arithmetic overflow");
+                    THROW_DECIMAL_BINARY_OP_OVERFLOW_EXCEPTION(
+                            DecimalV2Value(a[i]).to_string(), "multiply",
+                            DecimalV2Value(b[i]).to_string(),
+                            DecimalV2Value(i128_mul_result).to_string(), 
"decimalv2");
                 }
                 c[i] = (i128_mul_result - sgn[i]) / 
DecimalV2Value::ONE_BILLION + sgn[i];
                 if (c[i].value > max.value() || c[i].value < min.value()) {
-                    throw Exception(ErrorCode::ARITHMETIC_OVERFLOW_ERRROR, 
"Arithmetic overflow");
+                    THROW_DECIMAL_BINARY_OP_OVERFLOW_EXCEPTION(
+                            DecimalV2Value(a[i]).to_string(), "multiply",
+                            DecimalV2Value(b[i]).to_string(),
+                            DecimalV2Value(i128_mul_result).to_string(), 
"decimalv2");
                 }
             } else {
                 c[i] = (DecimalV2Value(a[i]).value() * 
DecimalV2Value(b[i]).value() - sgn[i]) /


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

Reply via email to