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