This is an automated email from the ASF dual-hosted git repository.
dataroaring pushed a commit to branch branch-3.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-3.0 by this push:
new 26d7a9f2325 branch-3.0: [fix](decimal)Fix the issue where decimal
multiplication produces incorrect results due to mul_overflow error #51533
(#51564)
26d7a9f2325 is described below
commit 26d7a9f2325e7924d93e3e47a4e8c9d249a5e967
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Tue Jun 10 10:18:29 2025 +0800
branch-3.0: [fix](decimal)Fix the issue where decimal multiplication
produces incorrect results due to mul_overflow error #51533 (#51564)
Cherry-picked from #51533
Co-authored-by: Mryange <[email protected]>
---
be/src/vec/common/arithmetic_overflow.h | 8 +-
be/test/common/check_overflow.cpp | 92 +++++++++++++++++++++
.../datatype_p0/decimalv3/test_decimalv3_cast3.out | Bin 1492 -> 1645 bytes
.../decimalv3/test_decimalv3_cast3.groovy | 7 ++
4 files changed, 100 insertions(+), 7 deletions(-)
diff --git a/be/src/vec/common/arithmetic_overflow.h
b/be/src/vec/common/arithmetic_overflow.h
index 6a586a8f689..e030957c600 100644
--- a/be/src/vec/common/arithmetic_overflow.h
+++ b/be/src/vec/common/arithmetic_overflow.h
@@ -117,13 +117,7 @@ inline bool mul_overflow(long long x, long long y, long
long& res) {
template <>
inline bool mul_overflow(__int128 x, __int128 y, __int128& res) {
- res = static_cast<unsigned __int128>(x) *
- static_cast<unsigned __int128>(y); /// Avoid signed integer overflow.
- if (!x || !y) return false;
-
- unsigned __int128 a = (x > 0) ? x : -x;
- unsigned __int128 b = (y > 0) ? y : -y;
- return ((a * b) / b != a) || (x > 0 && y > 0 && res < 0) || (x < 0 && y <
0 && res < 0);
+ return __builtin_mul_overflow(x, y, &res);
}
template <>
diff --git a/be/test/common/check_overflow.cpp
b/be/test/common/check_overflow.cpp
new file mode 100644
index 00000000000..8c6d5cde528
--- /dev/null
+++ b/be/test/common/check_overflow.cpp
@@ -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.
+
+#include <gtest/gtest.h>
+
+#include "vec/core/types.h"
+#include "vec/io/io_helper.h"
+#include "vec/io/reader_buffer.h"
+
+namespace doris::vectorized {
+
+struct CheckOverFlowTest : public testing::Test {
+ void SetUp() override {
+ // This function is called before each test.
+ }
+
+ void TearDown() override {
+ // This function is called after each test.
+ }
+
+ Int128 to_i128(std::string str) {
+ ReadBuffer rb = ReadBuffer(str.data(), str.size());
+ Int128 val;
+ EXPECT_TRUE(read_int_text_impl(val, rb));
+ return val;
+ };
+
+ wide::Int256 to_i256(std::string str) { return
wide::Int256::_impl::from_str(str.c_str()); };
+};
+
+TEST_F(CheckOverFlowTest, test_overflow_int128) {
+ {
+ Int128 a = to_i128("-15687000000000000000000");
+ Int128 b = to_i128("11000000000000000");
+ Int128 c;
+ EXPECT_TRUE(common::mul_overflow(a, b, c));
+ }
+
+ {
+ Int128 a = to_i128("-15687000000000000000000");
+ Int128 b = to_i128("-11000000000000000");
+ Int128 c;
+ EXPECT_TRUE(common::mul_overflow(a, b, c));
+ }
+
+ {
+ Int128 a = to_i128("1000");
+ Int128 b = to_i128("12000");
+ Int128 c;
+ EXPECT_FALSE(common::mul_overflow(a, b, c));
+ }
+}
+
+TEST_F(CheckOverFlowTest, test_overflow_int256) {
+ {
+ wide::Int256 a =
+
to_i256("-11579208923731619542357098500868790785326998466564056403945758400791");
+ wide::Int256 b =
to_i256("1157920892373161954235709850086879078532699846656405640394575");
+ wide::Int256 c;
+ EXPECT_TRUE(common::mul_overflow(a, b, c));
+ }
+
+ {
+ wide::Int256 a =
to_i256("-1157920892373161954235709850086879078532699846656405640394");
+ wide::Int256 b =
to_i256("-1157920892373161954235709850086879078532699846656405640394");
+ wide::Int256 c;
+ EXPECT_TRUE(common::mul_overflow(a, b, c));
+ }
+
+ {
+ wide::Int256 a = to_i256("1000");
+ wide::Int256 b = to_i256("12000");
+ wide::Int256 c;
+ EXPECT_FALSE(common::mul_overflow(a, b, c));
+ }
+}
+
+} // namespace doris::vectorized
diff --git
a/regression-test/data/datatype_p0/decimalv3/test_decimalv3_cast3.out
b/regression-test/data/datatype_p0/decimalv3/test_decimalv3_cast3.out
index 93460a101fd..b2500accd74 100644
Binary files
a/regression-test/data/datatype_p0/decimalv3/test_decimalv3_cast3.out and
b/regression-test/data/datatype_p0/decimalv3/test_decimalv3_cast3.out differ
diff --git
a/regression-test/suites/datatype_p0/decimalv3/test_decimalv3_cast3.groovy
b/regression-test/suites/datatype_p0/decimalv3/test_decimalv3_cast3.groovy
index d57f3b029ca..4e7b362915f 100644
--- a/regression-test/suites/datatype_p0/decimalv3/test_decimalv3_cast3.groovy
+++ b/regression-test/suites/datatype_p0/decimalv3/test_decimalv3_cast3.groovy
@@ -505,4 +505,11 @@ suite("test_decimalv3_cast3") {
exception "Arithmetic overflow"
}
sql "set enable_decimal256=false;"
+
+
+ sql """ set debug_skip_fold_constant = true;"""
+ qt_sql """ select -15687.000000000000000000 * 0.01100000000000000; """
+ qt_sql """ select -15687.000000000000000000 * 0.011000000000000000; """
+ qt_sql """ select -15687.000000000000000000 * 0.0110000000000000000; """
+ sql """ set debug_skip_fold_constant = false;"""
}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]