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]

Reply via email to