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 <[email protected]>
AuthorDate: Sun Jun 9 20:29:38 2024 +0800
[improvement](decimal) improve overflow error message (#34689) (#36078)
bp #34689
Co-authored-by: TengJianPing <[email protected]>
---
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: [email protected]
For additional commands, e-mail: [email protected]