This is an automated email from the ASF dual-hosted git repository.

morrysnow pushed a commit to branch branch-3.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-3.1 by this push:
     new 092dab7a5ac branch-3.1: [fix](core) Fix format round would core under 
boundary conditions. #53660 (#53857)
092dab7a5ac is described below

commit 092dab7a5acb1c8ea7dac1b95a019c4eca9c9511
Author: Mryange <[email protected]>
AuthorDate: Fri Jul 25 15:54:37 2025 +0800

    branch-3.1: [fix](core) Fix format round would core under boundary 
conditions. #53660 (#53857)
    
    picked from #53660
---
 be/src/exprs/math_functions.cpp                    |   2 +-
 be/src/vec/functions/function_string.h             |  50 +++++++++++-
 be/test/exprs/math_functions_test.cpp              |  87 +++++++++++++++++++++
 .../math_functions/test_format_round.out           | Bin 791 -> 11591 bytes
 .../math_functions/test_format_round.groovy        |  58 ++++++++++++++
 5 files changed, 193 insertions(+), 4 deletions(-)

diff --git a/be/src/exprs/math_functions.cpp b/be/src/exprs/math_functions.cpp
index 202a6eabea3..93e28efb733 100644
--- a/be/src/exprs/math_functions.cpp
+++ b/be/src/exprs/math_functions.cpp
@@ -83,7 +83,7 @@ double MathFunctions::my_double_round(double value, int64_t 
dec, bool dec_unsign
 
     if (dec_negative && std::isinf(tmp)) {
         tmp2 = 0.0;
-    } else if (!dec_negative && std::isinf(value_mul_tmp)) {
+    } else if (!dec_negative && !std::isfinite(value_mul_tmp)) {
         tmp2 = value;
     } else if (truncate) {
         if (value >= 0.0) {
diff --git a/be/src/vec/functions/function_string.h 
b/be/src/vec/functions/function_string.h
index 09122aaf51c..97c950d97b7 100644
--- a/be/src/vec/functions/function_string.h
+++ b/be/src/vec/functions/function_string.h
@@ -3365,6 +3365,44 @@ struct FormatRoundDoubleImpl {
         return {std::make_shared<DataTypeFloat64>(), 
std::make_shared<vectorized::DataTypeInt32>()};
     }
 
+    static std::string add_thousands_separator(const std::string& 
formatted_num) {
+        //  Find the position of the decimal point
+        size_t dot_pos = formatted_num.find('.');
+        if (dot_pos == std::string::npos) {
+            dot_pos = formatted_num.size();
+        }
+
+        // Handle the integer part
+        int start = (formatted_num[0] == '-') ? 1 : 0;
+        int digit_count = dot_pos - start;
+
+        // There is no need to add commas.
+        if (digit_count <= 3) {
+            return formatted_num;
+        }
+
+        std::string result;
+
+        if (start == 1) result += '-';
+
+        // Add the integer part (with comma)
+        int first_group = digit_count % 3;
+        if (first_group == 0) first_group = 3;
+        result.append(formatted_num, start, first_group);
+
+        for (size_t i = start + first_group; i < dot_pos; i += 3) {
+            result += ',';
+            result.append(formatted_num, i, 3);
+        }
+
+        // Add the decimal part (keep as it is)
+        if (dot_pos != formatted_num.size()) {
+            result.append(formatted_num, dot_pos);
+        }
+
+        return result;
+    }
+
     template <bool is_const>
     static Status execute(FunctionContext* context, ColumnString* 
result_column,
                           const ColumnPtr col_ptr, ColumnPtr 
decimal_places_col_ptr,
@@ -3382,9 +3420,15 @@ struct FormatRoundDoubleImpl {
             // round to `decimal_places` decimal places
             double value = 
MathFunctions::my_double_round(data_column->get_element(i),
                                                           decimal_places, 
false, false);
-            StringRef str = FormatRound::do_format_round(
-                    context, fmt::format("{:.{}f}", value, decimal_places), 
decimal_places);
-            result_column->insert_data(str.data, str.size);
+            std::string formatted_value = fmt::format("{:.{}f}", value, 
decimal_places);
+            if (std::isfinite(value)) {
+                auto res_str = add_thousands_separator(formatted_value);
+                result_column->insert_data(res_str.data(), res_str.size());
+            } else {
+                // if value is not finite, we just insert the original 
formatted value
+                // e.g. "inf", "-inf", "nan"
+                result_column->insert_data(formatted_value.data(), 
formatted_value.size());
+            }
         }
         return Status::OK();
     }
diff --git a/be/test/exprs/math_functions_test.cpp 
b/be/test/exprs/math_functions_test.cpp
new file mode 100644
index 00000000000..ce0fc635d64
--- /dev/null
+++ b/be/test/exprs/math_functions_test.cpp
@@ -0,0 +1,87 @@
+// 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 "exprs/math_functions.h"
+
+#include <gtest/gtest.h>
+
+#include <cmath>
+#include <limits>
+namespace doris {
+
+struct MathFunctionsTest : public ::testing::Test {};
+
+// Regular rounding test (truncate = false)
+TEST_F(MathFunctionsTest, DoubleRoundBasic) {
+    // Positive number rounding
+    EXPECT_DOUBLE_EQ(123.46, MathFunctions::my_double_round(123.456, 2, false, 
false));
+    EXPECT_DOUBLE_EQ(123.45, MathFunctions::my_double_round(123.454, 2, false, 
false));
+
+    // Negative number rounding
+    EXPECT_DOUBLE_EQ(-123.46, MathFunctions::my_double_round(-123.456, 2, 
false, false));
+    EXPECT_DOUBLE_EQ(-123.45, MathFunctions::my_double_round(-123.454, 2, 
false, false));
+
+    // Integer place rounding
+    EXPECT_DOUBLE_EQ(100.0,
+                     MathFunctions::my_double_round(123.456, -2, false, 
false)); // Hundreds place
+    EXPECT_DOUBLE_EQ(120.0,
+                     MathFunctions::my_double_round(123.456, -1, false, 
false)); // Tens place
+    EXPECT_DOUBLE_EQ(-100.0, MathFunctions::my_double_round(
+                                     -123.456, -2, false, false)); // Negative 
number hundreds place
+}
+
+// Truncation mode test (truncate = true)
+TEST_F(MathFunctionsTest, DoubleRoundTruncate) {
+    // Positive number truncation
+    EXPECT_DOUBLE_EQ(123.45, MathFunctions::my_double_round(123.456, 2, false, 
true));
+    EXPECT_DOUBLE_EQ(123.0, MathFunctions::my_double_round(123.789, 0, false, 
true));
+
+    // Negative number truncation (towards zero)
+    EXPECT_DOUBLE_EQ(-123.45, MathFunctions::my_double_round(-123.456, 2, 
false, true));
+    EXPECT_DOUBLE_EQ(-100.0, MathFunctions::my_double_round(-123.456, -2, 
false, true));
+}
+
+// Special value handling (Infinity, NaN)
+TEST_F(MathFunctionsTest, DoubleRoundSpecialValues) {
+    const double inf = std::numeric_limits<double>::infinity();
+    const double nan = std::numeric_limits<double>::quiet_NaN();
+
+    // Infinity remains unchanged
+    EXPECT_DOUBLE_EQ(inf, MathFunctions::my_double_round(inf, 2, false, 
false));
+    EXPECT_DOUBLE_EQ(-inf, MathFunctions::my_double_round(-inf, -3, true, 
true));
+
+    // NaN returns NaN
+    EXPECT_TRUE(std::isnan(MathFunctions::my_double_round(nan, 2, false, 
false)));
+
+    // Large precision causing overflow
+    EXPECT_DOUBLE_EQ(0.0, MathFunctions::my_double_round(123.456, -1000, 
false, false));
+    EXPECT_DOUBLE_EQ(123.456, MathFunctions::my_double_round(123.456, -1000, 
true,
+                                                             false)); // 
dec_unsigned handling
+}
+
+// Zero and boundary precision test
+TEST_F(MathFunctionsTest, DoubleRoundEdgeCases) {
+    // Zero value handling
+    EXPECT_DOUBLE_EQ(0.0, MathFunctions::my_double_round(0.0, 3, false, 
false));
+    EXPECT_DOUBLE_EQ(0.0, MathFunctions::my_double_round(-0.0, 2, true, true));
+
+    // Zero precision
+    EXPECT_DOUBLE_EQ(123.0, MathFunctions::my_double_round(123.456, 0, false, 
false));
+    EXPECT_DOUBLE_EQ(124.0, MathFunctions::my_double_round(123.789, 0, false, 
false)); // Rounding
+}
+
+}; // namespace doris
\ No newline at end of file
diff --git 
a/regression-test/data/query_p0/sql_functions/math_functions/test_format_round.out
 
b/regression-test/data/query_p0/sql_functions/math_functions/test_format_round.out
index aa9ccc5aa30..9a5e2caa452 100644
Binary files 
a/regression-test/data/query_p0/sql_functions/math_functions/test_format_round.out
 and 
b/regression-test/data/query_p0/sql_functions/math_functions/test_format_round.out
 differ
diff --git 
a/regression-test/suites/query_p0/sql_functions/math_functions/test_format_round.groovy
 
b/regression-test/suites/query_p0/sql_functions/math_functions/test_format_round.groovy
index 1af614f6aac..0c106563493 100644
--- 
a/regression-test/suites/query_p0/sql_functions/math_functions/test_format_round.groovy
+++ 
b/regression-test/suites/query_p0/sql_functions/math_functions/test_format_round.groovy
@@ -62,4 +62,62 @@ suite("test_format_round", "p0") {
         exception "it can not be less than 0"
     }
 
+    order_qt_format_round_14 """ SELECT format_round(9876.54321, 0) AS result; 
"""
+    order_qt_format_round_15 """ SELECT format_round(0.0000001, 7) AS result; 
"""
+    order_qt_format_round_16 """ SELECT format_round(999999999.999999, 6) AS 
result; """
+    order_qt_format_round_17 """ SELECT format_round(-123.456789, 3) AS 
result; """
+    order_qt_format_round_18 """ SELECT format_round(1.23456789, 10) AS 
result; """
+    order_qt_format_round_19 """ SELECT format_round(0.0, 2) AS result; """
+    order_qt_format_round_20 """ SELECT format_round(1234567890.123456789, 9) 
AS result; """
+    order_qt_format_round_21 """ SELECT format_round(0.0000000001, 10) AS 
result; """
+    order_qt_format_round_22 """ SELECT format_round(-999999999.999999, 6) AS 
result; """
+    order_qt_format_round_23 """ SELECT format_round(123.456789, 1) AS result; 
"""
+    order_qt_format_round_24 """ SELECT format_round(123.456789, 20) AS 
result; """
+    order_qt_format_round_25 """ SELECT format_round(1.7976931348623157E+308, 
2) AS result; """
+    order_qt_format_round_26 """ SELECT format_round(2.2250738585072014E-308, 
20) AS result; """
+    order_qt_format_round_27 """ SELECT format_round(0.0, 0) AS result; """
+    order_qt_format_round_28 """ SELECT format_round(0.0, 10) AS result; """
+    order_qt_format_round_29 """ SELECT format_round(1.0, 0) AS result; """
+    order_qt_format_round_30 """ SELECT format_round(1.0, 10) AS result; """
+    order_qt_format_round_31 """ SELECT 
format_round(0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,
 324) AS result; """
+    order_qt_format_round_32 """ SELECT format_round(1.7976931348623157E+308, 
0) AS result; """
+    order_qt_format_round_33 """ SELECT format_round(2.2250738585072014E-308, 
0) AS result; """
+    order_qt_format_round_34 """ SELECT format_round(1.7976931348623157E+308, 
10) AS result; """
+    order_qt_format_round_35 """ SELECT format_round(2.2250738585072014E-308, 
10) AS result; """
+    order_qt_format_round_36 """ SELECT format_round(1.7976931348623157E+308, 
324) AS result; """
+    order_qt_format_round_37 """ SELECT format_round(2.2250738585072014E-308, 
324) AS result; """
+    order_qt_format_round_38 """ SELECT format_round(1.0, 324) AS result; """
+    order_qt_format_round_39 """ SELECT format_round(0.0, 324) AS result; """
+    order_qt_format_round_40 """ SELECT 
format_round(0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,
 0) AS result; """
+    order_qt_format_round_41 """ SELECT 
format_round(0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,
 10) AS result; """
+    order_qt_format_round_42 """ SELECT 
format_round(0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,
 324) AS result; """
+    order_qt_format_round_43 """ SELECT format_round(1.0, 0) AS result; """
+    order_qt_format_round_44 """ SELECT format_round(1.0, 10) AS result; """
+    order_qt_format_round_45 """ SELECT format_round(1.0, 324) AS result; """
+    order_qt_format_round_46 """ SELECT format_round(0.0, 0) AS result; """
+    order_qt_format_round_47 """ SELECT format_round(0.0, 10) AS result; """
+    order_qt_format_round_48 """ SELECT format_round(0.0, 324) AS result; """
+    order_qt_format_round_49 """ SELECT format_round(1.7976931348623157E+308, 
0) AS result; """
+    order_qt_format_round_50 """ SELECT format_round(1.7976931348623157E+308, 
10) AS result; """
+    order_qt_format_round_51 """ SELECT format_round(1.7976931348623157E+308, 
324) AS result; """
+    order_qt_format_round_52 """ SELECT format_round(2.2250738585072014E-308, 
0) AS result; """
+    order_qt_format_round_53 """ SELECT format_round(2.2250738585072014E-308, 
10) AS result; """
+    order_qt_format_round_54 """ SELECT format_round(2.2250738585072014E-308, 
324) AS result; """
+    order_qt_format_round_55 """ SELECT 
format_round(0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,
 0) AS result; """
+    order_qt_format_round_56 """ SELECT 
format_round(0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,
 10) AS result; """
+    order_qt_format_round_57 """ SELECT 
format_round(0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,
 324) AS result; """
+    order_qt_format_round_58 """ SELECT format_round(1.0, 0) AS result; """
+    order_qt_format_round_59 """ SELECT format_round(1.0, 10) AS result; """
+    order_qt_format_round_60 """ SELECT format_round(1.0, 324) AS result; """
+    order_qt_format_round_61 """ SELECT format_round(0.0, 0) AS result; """
+    order_qt_format_round_62 """ SELECT format_round(0.0, 10) AS result; """
+    order_qt_format_round_63 """ SELECT format_round(0.0, 324) AS result; """
+    order_qt_format_round_64 """ SELECT format_round(1.7976931348623157E+308, 
0) AS result; """
+    order_qt_format_round_65 """ SELECT format_round(1.7976931348623157E+308, 
10) AS result; """
+    order_qt_format_round_66 """ SELECT format_round(1.7976931348623157E+308, 
324) AS result; """
+    order_qt_format_round_67 """ SELECT format_round(2.2250738585072014E-308, 
0) AS result; """
+    order_qt_format_round_68 """ SELECT format_round(2.2250738585072014E-308, 
10) AS result; """
+    order_qt_format_round_69 """ SELECT format_round(2.2250738585072014E-308, 
324) AS result; """
+    order_qt_format_round_70 """ SELECT 
format_round(0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,
 0) AS result; """
+    order_qt_format_round_71 """ SELECT 
format_round(0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,
 10) AS result; """
 }
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to