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

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


The following commit(s) were added to refs/heads/branch-2.0 by this push:
     new 6e12a0005ad [fix](money_format) fix money_format #31883 (#31901)
6e12a0005ad is described below

commit 6e12a0005ad6051ce6fb0b482a101da6c503e375
Author: zhiqiang <seuhezhiqi...@163.com>
AuthorDate: Thu Mar 7 14:12:10 2024 +0800

    [fix](money_format) fix money_format #31883 (#31901)
---
 be/src/vec/functions/function.cpp                  |  2 +-
 be/src/vec/functions/function_string.h             | 30 +++++++++++++++-------
 .../string_functions/test_string_function.out      | 24 +++++++++++++++++
 .../string_functions/test_string_function.groovy   |  8 ++++++
 4 files changed, 54 insertions(+), 10 deletions(-)

diff --git a/be/src/vec/functions/function.cpp 
b/be/src/vec/functions/function.cpp
index 6e7f6572ab8..a4ed868bdfd 100644
--- a/be/src/vec/functions/function.cpp
+++ b/be/src/vec/functions/function.cpp
@@ -172,7 +172,7 @@ Status 
PreparedFunctionImpl::default_implementation_for_constant_arguments(
         return Status::OK();
     }
 
-    // now all columns is const.
+    // now all columns are const.
     Block temporary_block;
 
     size_t arguments_size = args.size();
diff --git a/be/src/vec/functions/function_string.h 
b/be/src/vec/functions/function_string.h
index 45b1dec4f88..c2dbed38d39 100644
--- a/be/src/vec/functions/function_string.h
+++ b/be/src/vec/functions/function_string.h
@@ -26,6 +26,7 @@
 #include <array>
 #include <boost/iterator/iterator_facade.hpp>
 #include <cstddef>
+#include <cstdlib>
 #include <memory>
 #include <ostream>
 #include <tuple>
@@ -34,6 +35,7 @@
 
 // IWYU pragma: no_include <opentelemetry/common/threadlocal.h>
 #include "common/compiler_util.h" // IWYU pragma: keep
+#include "common/exception.h"
 #include "common/status.h"
 #include "gutil/strings/numbers.h"
 #include "gutil/strings/substitute.h"
@@ -2354,10 +2356,15 @@ template <typename Impl>
 class FunctionMoneyFormat : public IFunction {
 public:
     static constexpr auto name = "money_format";
-    static FunctionPtr create() { return 
std::make_shared<FunctionMoneyFormat<Impl>>(); }
+    static FunctionPtr create() { return 
std::make_shared<FunctionMoneyFormat>(); }
     String get_name() const override { return name; }
 
     DataTypePtr get_return_type_impl(const DataTypes& arguments) const 
override {
+        if (arguments.size() != 1) {
+            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
+                                   "Function {} requires exactly 1 argument", 
name);
+        }
+
         return std::make_shared<DataTypeString>();
     }
     DataTypes get_variadic_argument_types_impl() const override {
@@ -2430,9 +2437,11 @@ struct MoneyFormatDoubleImpl {
     static void execute(FunctionContext* context, ColumnString* result_column,
                         const ColumnPtr col_ptr, size_t input_rows_count) {
         const auto* data_column = assert_cast<const 
ColumnVector<Float64>*>(col_ptr.get());
+        // when scale is above 38, we will go here
         for (size_t i = 0; i < input_rows_count; i++) {
+            // truncate to 2 decimal places, keep same with mysql
             double value =
-                    
MathFunctions::my_double_round(data_column->get_element(i), 2, false, false);
+                    
MathFunctions::my_double_round(data_column->get_element(i), 2, false, true);
             StringRef str = MoneyFormat::do_money_format(context, 
fmt::format("{:.2f}", value));
             result_column->insert_data(str.data, str.size);
         }
@@ -2489,8 +2498,8 @@ struct MoneyFormatDecimalImpl {
         } else if (auto* decimal32_column =
                            
check_and_get_column<ColumnDecimal<Decimal32>>(*col_ptr)) {
             const UInt32 scale = decimal32_column->get_scale();
-            const auto multiplier =
-                    scale > 2 ? common::exp10_i32(scale - 2) : 
common::exp10_i32(2 - scale);
+            // scale is up to 9, so exp10_i32 is enough
+            const auto multiplier = 
common::exp10_i32(std::abs(static_cast<int>(scale - 2)));
             for (size_t i = 0; i < input_rows_count; i++) {
                 Decimal32 frac_part = decimal32_column->get_fractional_part(i);
                 if (scale > 2) {
@@ -2508,8 +2517,8 @@ struct MoneyFormatDecimalImpl {
         } else if (auto* decimal64_column =
                            
check_and_get_column<ColumnDecimal<Decimal64>>(*col_ptr)) {
             const UInt32 scale = decimal64_column->get_scale();
-            const auto multiplier =
-                    scale > 2 ? common::exp10_i32(scale - 2) : 
common::exp10_i32(2 - scale);
+            // 9 < scale <= 18
+            const auto multiplier = 
common::exp10_i64(std::abs(static_cast<int>(scale - 2)));
             for (size_t i = 0; i < input_rows_count; i++) {
                 Decimal64 frac_part = decimal64_column->get_fractional_part(i);
                 if (scale > 2) {
@@ -2527,8 +2536,8 @@ struct MoneyFormatDecimalImpl {
         } else if (auto* decimal128_column =
                            
check_and_get_column<ColumnDecimal<Decimal128I>>(*col_ptr)) {
             const UInt32 scale = decimal128_column->get_scale();
-            const auto multiplier =
-                    scale > 2 ? common::exp10_i32(scale - 2) : 
common::exp10_i32(2 - scale);
+            // 18 < scale <= 38
+            const auto multiplier = 
common::exp10_i128(std::abs(static_cast<int>(scale - 2)));
             for (size_t i = 0; i < input_rows_count; i++) {
                 Decimal128I frac_part = 
decimal128_column->get_fractional_part(i);
                 if (scale > 2) {
@@ -2543,6 +2552,9 @@ struct MoneyFormatDecimalImpl {
 
                 result_column->insert_data(str.data, str.size);
             }
+        } else {
+            throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
+                                   "Not supported input argument type {}", 
col_ptr->get_name());
         }
     }
 };
@@ -3027,7 +3039,7 @@ public:
 // 
+---------------------------------------------------------------------------------------------+
 // | char(0xe5, 0xa4, 0x9a, 0xe7, 0x9d, 0xbf, 0xe4, 0xb8, 0x9d, 68, 111, 114, 
105, 115 using utf8) |
 // 
+---------------------------------------------------------------------------------------------+
-// | 多睿丝Doris                                                                  
               |
+// | 多睿丝 Doris                                                                 
                |
 // 
+---------------------------------------------------------------------------------------------+
 // mysql> select char(68, 111, 114, 0, 105, null, 115 using utf8);
 // +--------------------------------------------------+
diff --git 
a/regression-test/data/nereids_p0/sql_functions/string_functions/test_string_function.out
 
b/regression-test/data/nereids_p0/sql_functions/string_functions/test_string_function.out
index c0bffd9e929..1adffb0540b 100644
--- 
a/regression-test/data/nereids_p0/sql_functions/string_functions/test_string_function.out
+++ 
b/regression-test/data/nereids_p0/sql_functions/string_functions/test_string_function.out
@@ -164,6 +164,30 @@ ab d
 -- !sql --
 1,123.40
 
+-- !sql --
+1.12
+
+-- !sql_decimal32 --
+1.12
+
+-- !sql_decimal64 --
+1.12
+
+-- !sql_decimal64 --
+1.12
+
+-- !sql_decimal128 --
+1.12
+
+-- !sql_decimal128 --
+1.12
+
+-- !sql_float64 --
+1.12
+
+-- !sql_float64 --
+1.12
+
 -- !sql --
 true
 
diff --git 
a/regression-test/suites/nereids_p0/sql_functions/string_functions/test_string_function.groovy
 
b/regression-test/suites/nereids_p0/sql_functions/string_functions/test_string_function.groovy
index b1eb8aeefaa..a03b2da1fd2 100644
--- 
a/regression-test/suites/nereids_p0/sql_functions/string_functions/test_string_function.groovy
+++ 
b/regression-test/suites/nereids_p0/sql_functions/string_functions/test_string_function.groovy
@@ -102,6 +102,14 @@ suite("test_string_function") {
     qt_sql "select money_format(17014116);"
     qt_sql "select money_format(1123.456);"
     qt_sql "select money_format(1123.4);"
+    qt_sql "select money_format(1.1249);"
+    qt_sql_decimal32 "select money_format(cast(concat('1.124', repeat('9', 5)) 
as DECIMAL(9, 8)));"
+    qt_sql_decimal64 "select money_format(cast(concat('1.124', repeat('9', 6)) 
as DECIMAL(10, 9)));"
+    qt_sql_decimal64 "select money_format(cast(concat('1.124', repeat('9', 
14)) as DECIMAL(18, 17)));"
+    qt_sql_decimal128 "select money_format(cast(concat('1.124', repeat('9', 
15)) as DECIMAL(19, 18)));"
+    qt_sql_decimal128 "select money_format(cast(concat('1.124', repeat('9', 
34)) as DECIMAL(38, 37)));"
+    qt_sql_float64 "select money_format(cast(concat('1.124', repeat('9', 35)) 
as DOUBLE));"
+    qt_sql_float64 "select money_format(cast(concat('1.124', repeat('9', 70)) 
as DOUBLE));"
 
     qt_sql "select null_or_empty(null);"
     qt_sql "select null_or_empty(\"\");"


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to