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