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