This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new b4ce532033d [fix](money_format) fix money_format #31883
b4ce532033d is described below
commit b4ce532033d6a1c23200b69714ba69d03d6bbbb3
Author: zhiqiang <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]