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

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

commit 137666651493115c1730c40d65abf8af9d727b42
Author: zhiqiang <seuhezhiqi...@163.com>
AuthorDate: Thu Mar 7 11:26:41 2024 +0800

    [fix](money_format) fix money_format #31883
---
 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 6a033d52f03..b4b0e82a0aa 100644
--- a/be/src/vec/functions/function.cpp
+++ b/be/src/vec/functions/function.cpp
@@ -141,7 +141,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 c789345743e..a1f5c9e1306 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 <iomanip>
 #include <memory>
 #include <ostream>
@@ -36,6 +37,7 @@
 #include <vector>
 
 #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"
@@ -2941,10 +2943,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 {
@@ -3017,9 +3024,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);
         }
@@ -3076,8 +3085,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) {
@@ -3095,8 +3104,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) {
@@ -3114,8 +3123,8 @@ struct MoneyFormatDecimalImpl {
         } else if (auto* decimal128_column =
                            
check_and_get_column<ColumnDecimal<Decimal128V3>>(*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++) {
                 Decimal128V3 frac_part = 
decimal128_column->get_fractional_part(i);
                 if (scale > 2) {
@@ -3130,6 +3139,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());
         }
         // TODO: decimal256
         /* else if (auto* decimal256_column =
@@ -3635,7 +3647,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 7f2e30b5c14..090ec198a7b 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
@@ -170,6 +170,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 64fcc2e372a..20c8294b114 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
@@ -104,6 +104,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