This is an automated email from the ASF dual-hosted git repository.
yiguolei 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 1d3a21f6d3f [fix](round) fix round decimal128 overflow (#37733)
1d3a21f6d3f is described below
commit 1d3a21f6d3f76acee7e3a1238bc27801fe91edf6
Author: camby <[email protected]>
AuthorDate: Wed Jul 17 00:48:34 2024 +0800
[fix](round) fix round decimal128 overflow (#37733)
## Proposed changes
Issue Number: close #https://github.com/apache/doris/issues/37143
<!--Describe your changes.-->
---
be/src/vec/exec/format/format_common.h | 4 +++-
be/src/vec/functions/round.h | 17 +++++++++------
.../math_functions/test_round_overflow.out | 10 +++++++++
.../math_functions/test_round_overflow.groovy | 25 ++++++++++++++++++++++
4 files changed, 48 insertions(+), 8 deletions(-)
diff --git a/be/src/vec/exec/format/format_common.h
b/be/src/vec/exec/format/format_common.h
index 4227a2128d2..3edf021ad27 100644
--- a/be/src/vec/exec/format/format_common.h
+++ b/be/src/vec/exec/format/format_common.h
@@ -33,7 +33,7 @@ struct DecimalScaleParams {
int64_t scale_factor = 1;
template <typename DecimalPrimitiveType>
- static inline constexpr DecimalPrimitiveType get_scale_factor(int32_t n) {
+ static inline constexpr DecimalPrimitiveType::NativeType
get_scale_factor(int32_t n) {
if constexpr (std::is_same_v<DecimalPrimitiveType, Decimal32>) {
return common::exp10_i32(n);
} else if constexpr (std::is_same_v<DecimalPrimitiveType, Decimal64>) {
@@ -42,6 +42,8 @@ struct DecimalScaleParams {
return common::exp10_i128(n);
} else if constexpr (std::is_same_v<DecimalPrimitiveType,
Decimal128V3>) {
return common::exp10_i128(n);
+ } else if constexpr (std::is_same_v<DecimalPrimitiveType, Decimal256>)
{
+ return common::exp10_i256(n);
} else {
static_assert(!sizeof(DecimalPrimitiveType),
"All types must be matched with if constexpr.");
diff --git a/be/src/vec/functions/round.h b/be/src/vec/functions/round.h
index a17865914c4..c8a2cd5d4e9 100644
--- a/be/src/vec/functions/round.h
+++ b/be/src/vec/functions/round.h
@@ -32,6 +32,7 @@
#include "vec/core/types.h"
#include "vec/data_types/data_type.h"
#include "vec/data_types/data_type_nullable.h"
+#include "vec/exec/format/format_common.h"
#include "vec/functions/function.h"
#if defined(__SSE4_1__) || defined(__aarch64__)
#include "util/sse_util.hpp"
@@ -126,7 +127,7 @@ struct IntegerRoundingComputation {
__builtin_unreachable();
}
- static ALWAYS_INLINE T compute(T x, T scale, size_t target_scale) {
+ static ALWAYS_INLINE T compute(T x, T scale, T target_scale) {
switch (scale_mode) {
case ScaleMode::Zero:
case ScaleMode::Positive:
@@ -163,21 +164,22 @@ public:
Int16 out_scale) {
Int16 scale_arg = in_scale - out_scale;
if (scale_arg > 0) {
- size_t scale = int_exp10(scale_arg);
+ auto scale = DecimalScaleParams::get_scale_factor<T>(scale_arg);
const NativeType* __restrict p_in = reinterpret_cast<const
NativeType*>(in.data());
const NativeType* end_in = reinterpret_cast<const
NativeType*>(in.data()) + in.size();
NativeType* __restrict p_out =
reinterpret_cast<NativeType*>(out.data());
if (out_scale < 0) {
+ auto negative_scale =
DecimalScaleParams::get_scale_factor<T>(-out_scale);
while (p_in < end_in) {
- Op::compute(p_in, scale, p_out, int_exp10(-out_scale));
+ *p_out = Op::compute(*p_in, scale, negative_scale);
++p_in;
++p_out;
}
} else {
while (p_in < end_in) {
- Op::compute(p_in, scale, p_out, 1);
+ *p_out = Op::compute(*p_in, scale, 1);
++p_in;
++p_out;
}
@@ -191,11 +193,12 @@ public:
Int16 out_scale) {
Int16 scale_arg = in_scale - out_scale;
if (scale_arg > 0) {
- size_t scale = int_exp10(scale_arg);
+ auto scale = DecimalScaleParams::get_scale_factor<T>(scale_arg);
if (out_scale < 0) {
- Op::compute(&in, scale, &out, int_exp10(-out_scale));
+ auto negative_scale =
DecimalScaleParams::get_scale_factor<T>(-out_scale);
+ out = Op::compute(in, scale, negative_scale);
} else {
- Op::compute(&in, scale, &out, 1);
+ out = Op::compute(in, scale, 1);
}
} else {
memcpy(&out, &in, sizeof(NativeType));
diff --git
a/regression-test/data/nereids_p0/sql_functions/math_functions/test_round_overflow.out
b/regression-test/data/nereids_p0/sql_functions/math_functions/test_round_overflow.out
new file mode 100644
index 00000000000..a18cc094872
--- /dev/null
+++
b/regression-test/data/nereids_p0/sql_functions/math_functions/test_round_overflow.out
@@ -0,0 +1,10 @@
+-- This file is automatically generated. You should know what you did if you
want to edit this
+-- !select1 --
+186
+
+-- !select2 --
+0
+
+-- !select3 --
+20000000000000000000000
+
diff --git
a/regression-test/suites/nereids_p0/sql_functions/math_functions/test_round_overflow.groovy
b/regression-test/suites/nereids_p0/sql_functions/math_functions/test_round_overflow.groovy
new file mode 100644
index 00000000000..12311537c27
--- /dev/null
+++
b/regression-test/suites/nereids_p0/sql_functions/math_functions/test_round_overflow.groovy
@@ -0,0 +1,25 @@
+// 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.
+
+suite("test_round_overflow") {
+ sql "SET enable_nereids_planner=true"
+ sql "SET enable_fallback_to_original_planner=false"
+
+ qt_select1 "select
round(coalesce(186,-33280029.8473323000000000000000000));"
+ qt_select2 "select
round(coalesce(186,-33280029.8473323000000000000000000), -20);"
+ qt_select3 "select
round(coalesce(18618500001234567890123.0,-33280029.847332300000000),-22);"
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]