From c99bc07d2c334a97832bc90b45bfdca5c852ddc7 Mon Sep 17 00:00:00 2001 From: xzhangxian1008 Date: Fri, 1 Jul 2022 17:08:08 +0800 Subject: [PATCH 01/11] fix --- dbms/src/Functions/FunctionsRound.h | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/dbms/src/Functions/FunctionsRound.h b/dbms/src/Functions/FunctionsRound.h index 356d7f68cda..0915488bfc9 100644 --- a/dbms/src/Functions/FunctionsRound.h +++ b/dbms/src/Functions/FunctionsRound.h @@ -1150,6 +1150,7 @@ struct TiDBDecimalRound // rounding. auto absolute_value = toSafeUnsigned(input.value); + auto carry = 0; if (frac < info.input_scale) { FracType frac_index = info.input_scale - frac; @@ -1162,7 +1163,21 @@ struct TiDBDecimalRound if (remainder >= base / 2) { // round up. + auto absolute_before = absolute_value; absolute_value += base; + + // check if carry occurs + auto absolute_tmp = absolute_value; + while (absolute_tmp >= 10 && absolute_before >= 10) + { + absolute_tmp /= 10; + absolute_before /= 10; + } + + if (absolute_tmp >= 10) + { + carry = 1; /// carry occurs + } } } @@ -1186,7 +1201,7 @@ struct TiDBDecimalRound scaled_value *= PowForOutput::result[-difference]; // check overflow and construct result. - if (scaled_value > DecimalMaxValue::get(info.output_prec)) + if (scaled_value > DecimalMaxValue::get(info.output_prec + carry)) throw TiFlashException("Data truncated", Errors::Decimal::Overflow); auto result = static_cast(scaled_value); From d21ac2f682daedb3694e3ff799db45af51b285a9 Mon Sep 17 00:00:00 2001 From: xzhangxian1008 Date: Fri, 1 Jul 2022 17:10:08 +0800 Subject: [PATCH 02/11] update --- dbms/src/Functions/FunctionsRound.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Functions/FunctionsRound.h b/dbms/src/Functions/FunctionsRound.h index 0915488bfc9..b0e1fd260e7 100644 --- a/dbms/src/Functions/FunctionsRound.h +++ b/dbms/src/Functions/FunctionsRound.h @@ -1201,7 +1201,7 @@ struct TiDBDecimalRound scaled_value *= PowForOutput::result[-difference]; // check overflow and construct result. - if (scaled_value > DecimalMaxValue::get(info.output_prec + carry)) + if (scaled_value > DecimalMaxValue::get(info.output_prec + carry)) throw TiFlashException("Data truncated", Errors::Decimal::Overflow); auto result = static_cast(scaled_value); From 726e12f9c3f7e1f17392a8bca353bf679dde8bc4 Mon Sep 17 00:00:00 2001 From: xzhangxian1008 Date: Tue, 5 Jul 2022 11:13:00 +0800 Subject: [PATCH 03/11] update --- dbms/src/Functions/FunctionsRound.h | 30 +++++++------------ dbms/src/Functions/FunctionsString.cpp | 15 ++++++++-- .../Functions/tests/gtest_strings_format.cpp | 14 ++++++--- 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/dbms/src/Functions/FunctionsRound.h b/dbms/src/Functions/FunctionsRound.h index b0e1fd260e7..65bf1626c60 100644 --- a/dbms/src/Functions/FunctionsRound.h +++ b/dbms/src/Functions/FunctionsRound.h @@ -1126,6 +1126,16 @@ struct TiDBDecimalRoundInfo , output_prec(getDecimalPrecision(output_type, 0)) , output_scale(getDecimalScale(output_type, 0)) {} + + TiDBDecimalRoundInfo(const FracType & input_prec_, const FracType & input_scale_, const FracType & output_prec_, const FracType & output_scale_) + : input_prec(input_prec_) + , input_scale(input_scale_) + , input_int_prec(input_prec - input_scale) + , output_prec(output_prec_) + , output_scale(output_scale_) + {} + + void setOutputScale(const FracType & output_scale_) { output_scale = output_scale_; } }; template @@ -1150,7 +1160,6 @@ struct TiDBDecimalRound // rounding. auto absolute_value = toSafeUnsigned(input.value); - auto carry = 0; if (frac < info.input_scale) { FracType frac_index = info.input_scale - frac; @@ -1163,21 +1172,7 @@ struct TiDBDecimalRound if (remainder >= base / 2) { // round up. - auto absolute_before = absolute_value; absolute_value += base; - - // check if carry occurs - auto absolute_tmp = absolute_value; - while (absolute_tmp >= 10 && absolute_before >= 10) - { - absolute_tmp /= 10; - absolute_before /= 10; - } - - if (absolute_tmp >= 10) - { - carry = 1; /// carry occurs - } } } @@ -1197,11 +1192,8 @@ struct TiDBDecimalRound auto scaled_value = static_cast(absolute_value); - if (difference < 0) - scaled_value *= PowForOutput::result[-difference]; - // check overflow and construct result. - if (scaled_value > DecimalMaxValue::get(info.output_prec + carry)) + if (scaled_value > DecimalMaxValue::get(info.output_prec)) throw TiFlashException("Data truncated", Errors::Decimal::Overflow); auto result = static_cast(scaled_value); diff --git a/dbms/src/Functions/FunctionsString.cpp b/dbms/src/Functions/FunctionsString.cpp index b9f20e45134..65c6936fb80 100644 --- a/dbms/src/Functions/FunctionsString.cpp +++ b/dbms/src/Functions/FunctionsString.cpp @@ -4565,6 +4565,9 @@ class FormatImpl : public IFunction const auto & number_base_type = block.getByPosition(arguments[0]).type; const auto & precision_base_type = block.getByPosition(arguments[1]).type; + auto precision_base_col = block.getByPosition(arguments[1]).column; + auto precision_base_col_size = precision_base_col->size(); + auto col_res = ColumnString::create(); auto val_num = block.getByPosition(arguments[0]).column->size(); @@ -4573,7 +4576,14 @@ class FormatImpl : public IFunction using NumberFieldType = typename NumberType::FieldType; using NumberColVec = std::conditional_t, ColumnDecimal, ColumnVector>; const auto * number_raw = block.getByPosition(arguments[0]).column.get(); - TiDBDecimalRoundInfo info{number_type, number_type}; + + auto prec = getDecimalPrecision(number_type, 0); + auto scale = getDecimalScale(number_type, 0); + + /// output_scale is the second parameter of the 'format' function + auto output_scale = precision_base_col_size > 0 ? (*precision_base_col)[0].get() : scale; + output_scale = output_scale < 0 ? 0 : output_scale; /// Ensure output_scale >= 0 + TiDBDecimalRoundInfo info{prec, scale, prec, output_scale}; return getPrecisionType(precision_base_type, [&](const auto & precision_type, bool) { using PrecisionType = std::decay_t; @@ -4612,6 +4622,7 @@ class FormatImpl : public IFunction for (size_t i = 0; i != val_num; ++i) { size_t max_num_decimals = getMaxNumDecimals(precision_array[i]); + info.setOutputScale(max_num_decimals); format(number_array[i], max_num_decimals, info, col_res->getChars(), col_res->getOffsets()); } } @@ -4700,7 +4711,7 @@ class FormatImpl : public IFunction static std::string number2Str(T number, const TiDBDecimalRoundInfo & info [[maybe_unused]]) { if constexpr (IsDecimal) - return number.toString(info.output_scale); + return number.toString(std::min(info.input_scale, info.output_scale)); else { static_assert(std::is_floating_point_v || std::is_integral_v); diff --git a/dbms/src/Functions/tests/gtest_strings_format.cpp b/dbms/src/Functions/tests/gtest_strings_format.cpp index 2d571a9bb1b..721e2d1e7d8 100644 --- a/dbms/src/Functions/tests/gtest_strings_format.cpp +++ b/dbms/src/Functions/tests/gtest_strings_format.cpp @@ -34,12 +34,13 @@ class StringFormat : public DB::tests::FunctionTest using FieldType = DecimalField; using NullableDecimal = Nullable; ASSERT_COLUMN_EQ( - createColumn>({"0.0000", "-0.0120", "0.0120", "12,332.1000", "12,332", "12,332", "12,332.300000000000000000000000000000", "-12,332.30000", "-1,000.0", "-333.33", {}}), + createColumn>({"0.0000", "-0.0120", "0.0120", "12,332.1000", "12,332", "12,332", "12,332.300000000000000000000000000000", "-12,332.30000", "-1,000.0", "-333.33", {}, "99,999.9999000000", "100,000.000", "100,000"}), executeFunction( func_name, createColumn( std::make_tuple(precision, 4), - {FieldType(static_cast(0), 4), + { + FieldType(static_cast(0), 4), FieldType(static_cast(-120), 4), FieldType(static_cast(120), 4), FieldType(static_cast(123321000), 4), @@ -49,8 +50,13 @@ class StringFormat : public DB::tests::FunctionTest FieldType(static_cast(-123323000), 4), FieldType(static_cast(-9999999), 4), FieldType(static_cast(-3333330), 4), - FieldType(static_cast(0), 0)}), - createColumn>({4, 4, 4, 4, 0, -1, 31, 5, 1, 2, {}}))); + FieldType(static_cast(0), 0), + FieldType(static_cast(999999999), 4), + FieldType(static_cast(999999999), 4), + FieldType(static_cast(999999999), 4) + }), + createColumn>({4, 4, 4, 4, 0, -1, 31, 5, 1, 2, {}, 10, 3, -5}) + )); ASSERT_COLUMN_EQ( createColumn>({"12,332.100", "-12,332.300", "-1,000.000", "-333.333"}), executeFunction( From 40f1a4d0efcde19e0c2b340cd0c3bda9baba2a4f Mon Sep 17 00:00:00 2001 From: xzhangxian1008 Date: Tue, 5 Jul 2022 11:15:52 +0800 Subject: [PATCH 04/11] format --- dbms/src/Functions/tests/gtest_strings_format.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/dbms/src/Functions/tests/gtest_strings_format.cpp b/dbms/src/Functions/tests/gtest_strings_format.cpp index 721e2d1e7d8..f34c592f3b6 100644 --- a/dbms/src/Functions/tests/gtest_strings_format.cpp +++ b/dbms/src/Functions/tests/gtest_strings_format.cpp @@ -39,8 +39,7 @@ class StringFormat : public DB::tests::FunctionTest func_name, createColumn( std::make_tuple(precision, 4), - { - FieldType(static_cast(0), 4), + {FieldType(static_cast(0), 4), FieldType(static_cast(-120), 4), FieldType(static_cast(120), 4), FieldType(static_cast(123321000), 4), @@ -53,10 +52,8 @@ class StringFormat : public DB::tests::FunctionTest FieldType(static_cast(0), 0), FieldType(static_cast(999999999), 4), FieldType(static_cast(999999999), 4), - FieldType(static_cast(999999999), 4) - }), - createColumn>({4, 4, 4, 4, 0, -1, 31, 5, 1, 2, {}, 10, 3, -5}) - )); + FieldType(static_cast(999999999), 4)}), + createColumn>({4, 4, 4, 4, 0, -1, 31, 5, 1, 2, {}, 10, 3, -5}))); ASSERT_COLUMN_EQ( createColumn>({"12,332.100", "-12,332.300", "-1,000.000", "-333.333"}), executeFunction( From 339014a935ffb8d82216934328b03793f09d1fa3 Mon Sep 17 00:00:00 2001 From: xzhangxian1008 Date: Tue, 5 Jul 2022 15:14:47 +0800 Subject: [PATCH 05/11] update --- dbms/src/Functions/FunctionsRound.h | 12 +++++++----- dbms/src/Functions/FunctionsString.cpp | 18 +++++++----------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/dbms/src/Functions/FunctionsRound.h b/dbms/src/Functions/FunctionsRound.h index 65bf1626c60..62f8ddf79d0 100644 --- a/dbms/src/Functions/FunctionsRound.h +++ b/dbms/src/Functions/FunctionsRound.h @@ -1127,15 +1127,17 @@ struct TiDBDecimalRoundInfo , output_scale(getDecimalScale(output_type, 0)) {} - TiDBDecimalRoundInfo(const FracType & input_prec_, const FracType & input_scale_, const FracType & output_prec_, const FracType & output_scale_) + TiDBDecimalRoundInfo(const FracType & input_prec_, const FracType & input_scale_) : input_prec(input_prec_) , input_scale(input_scale_) - , input_int_prec(input_prec - input_scale) - , output_prec(output_prec_) - , output_scale(output_scale_) + , input_int_prec(input_prec_ - input_scale_) {} - void setOutputScale(const FracType & output_scale_) { output_scale = output_scale_; } + void setOutputPrecAndScale(const FracType & output_prec_, const FracType & output_scale_) + { + output_prec = output_prec_; + output_scale = output_scale_; + } }; template diff --git a/dbms/src/Functions/FunctionsString.cpp b/dbms/src/Functions/FunctionsString.cpp index 65c6936fb80..62bde365c60 100644 --- a/dbms/src/Functions/FunctionsString.cpp +++ b/dbms/src/Functions/FunctionsString.cpp @@ -4565,9 +4565,6 @@ class FormatImpl : public IFunction const auto & number_base_type = block.getByPosition(arguments[0]).type; const auto & precision_base_type = block.getByPosition(arguments[1]).type; - auto precision_base_col = block.getByPosition(arguments[1]).column; - auto precision_base_col_size = precision_base_col->size(); - auto col_res = ColumnString::create(); auto val_num = block.getByPosition(arguments[0]).column->size(); @@ -4577,14 +4574,11 @@ class FormatImpl : public IFunction using NumberColVec = std::conditional_t, ColumnDecimal, ColumnVector>; const auto * number_raw = block.getByPosition(arguments[0]).column.get(); - auto prec = getDecimalPrecision(number_type, 0); - auto scale = getDecimalScale(number_type, 0); - - /// output_scale is the second parameter of the 'format' function - auto output_scale = precision_base_col_size > 0 ? (*precision_base_col)[0].get() : scale; - output_scale = output_scale < 0 ? 0 : output_scale; /// Ensure output_scale >= 0 - TiDBDecimalRoundInfo info{prec, scale, prec, output_scale}; + auto input_prec = getDecimalPrecision(number_type, 0); + auto input_scale = getDecimalScale(number_type, 0); + TiDBDecimalRoundInfo info{input_prec, input_scale}; + return getPrecisionType(precision_base_type, [&](const auto & precision_type, bool) { using PrecisionType = std::decay_t; using PrecisionFieldType = typename PrecisionType::FieldType; @@ -4601,6 +4595,7 @@ class FormatImpl : public IFunction for (size_t i = 0; i != val_num; ++i) { size_t max_num_decimals = getMaxNumDecimals(precision_array[i]); + info.setOutputPrecAndScale(input_prec, max_num_decimals); format(const_number, max_num_decimals, info, col_res->getChars(), col_res->getOffsets()); } } @@ -4612,6 +4607,7 @@ class FormatImpl : public IFunction if (const auto * col1_const = checkAndGetColumnConst(precision_raw)) { size_t max_num_decimals = getMaxNumDecimals(col1_const->template getValue()); + info.setOutputPrecAndScale(input_prec, max_num_decimals); for (const auto & number : col0_column->getData()) format(number, max_num_decimals, info, col_res->getChars(), col_res->getOffsets()); } @@ -4622,7 +4618,7 @@ class FormatImpl : public IFunction for (size_t i = 0; i != val_num; ++i) { size_t max_num_decimals = getMaxNumDecimals(precision_array[i]); - info.setOutputScale(max_num_decimals); + info.setOutputPrecAndScale(input_prec, max_num_decimals); format(number_array[i], max_num_decimals, info, col_res->getChars(), col_res->getOffsets()); } } From e9315215b4ff6064323a2fb53f6db4374b9b6bd8 Mon Sep 17 00:00:00 2001 From: xzhangxian1008 Date: Tue, 5 Jul 2022 15:15:38 +0800 Subject: [PATCH 06/11] format --- dbms/src/Functions/FunctionsString.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Functions/FunctionsString.cpp b/dbms/src/Functions/FunctionsString.cpp index 62bde365c60..80ac1096688 100644 --- a/dbms/src/Functions/FunctionsString.cpp +++ b/dbms/src/Functions/FunctionsString.cpp @@ -4578,7 +4578,7 @@ class FormatImpl : public IFunction auto input_scale = getDecimalScale(number_type, 0); TiDBDecimalRoundInfo info{input_prec, input_scale}; - + return getPrecisionType(precision_base_type, [&](const auto & precision_type, bool) { using PrecisionType = std::decay_t; using PrecisionFieldType = typename PrecisionType::FieldType; From 01dd580bc090c328a00b5f40326b86e16ce3e8a0 Mon Sep 17 00:00:00 2001 From: xzhangxian1008 Date: Fri, 8 Jul 2022 10:01:29 +0800 Subject: [PATCH 07/11] enable ut --- dbms/src/Functions/tests/gtest_strings_format.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/dbms/src/Functions/tests/gtest_strings_format.cpp b/dbms/src/Functions/tests/gtest_strings_format.cpp index f34c592f3b6..8f3b899316e 100644 --- a/dbms/src/Functions/tests/gtest_strings_format.cpp +++ b/dbms/src/Functions/tests/gtest_strings_format.cpp @@ -65,8 +65,6 @@ class StringFormat : public DB::tests::FunctionTest FieldType(static_cast(-9999999), 4), FieldType(static_cast(-3333330), 4)}), createConstColumn>(4, 3))); - /// known issue https://github.com/pingcap/tiflash/issues/4891 - /* ASSERT_COLUMN_EQ( createColumn>({"-999.9999", "-1,000", "-1,000", "-999.999900000000000000000000000000", "-999.99990", "-1,000.0", "-1,000.00"}), executeFunction( @@ -77,7 +75,7 @@ class StringFormat : public DB::tests::FunctionTest FieldType(static_cast(-9999999), 4)), createColumn>({4, 0, -1, 31, 5, 1, 2}))); ASSERT_COLUMN_EQ( - createConstColumn>(1, "-1,000.000"), + createConstColumn(1, "-1,000.000"), executeFunction( func_name, createConstColumn( @@ -85,7 +83,6 @@ class StringFormat : public DB::tests::FunctionTest 1, FieldType(static_cast(-9999999), 4)), createConstColumn>(1, 3))); - */ ASSERT_COLUMN_EQ( createColumn>({"12,332.1000", "12,332", "12,332.300000000000000000000000000000", "-12,332.30000", "-1,000.0", "-333.33", {}}), executeFunction( @@ -111,8 +108,6 @@ class StringFormat : public DB::tests::FunctionTest FieldType(static_cast(-9999999), 4), FieldType(static_cast(-3333330), 4)}), createConstColumn>(4, 3))); - /// known issue https://github.com/pingcap/tiflash/issues/4891 - /* ASSERT_COLUMN_EQ( createColumn>({"-999.9999", "-1,000", "-999.999900000000000000000000000000", "-999.99990", "-1,000.0", "-1,000.00"}), executeFunction( @@ -123,7 +118,7 @@ class StringFormat : public DB::tests::FunctionTest FieldType(static_cast(-9999999), 4)), createColumn>({4, 0, 31, 5, 1, 2}))); ASSERT_COLUMN_EQ( - createConstColumn>(1, "-1,000.000"), + createConstColumn(1, "-1,000.000"), executeFunction( func_name, createConstColumn( @@ -131,7 +126,6 @@ class StringFormat : public DB::tests::FunctionTest 1, FieldType(static_cast(-9999999), 4)), createConstColumn>(1, 3))); - */ } template From dba518e8393f1c3a2ad916bd899621685c83910e Mon Sep 17 00:00:00 2001 From: xzhangxian1008 Date: Sat, 9 Jul 2022 17:06:52 +0800 Subject: [PATCH 08/11] update --- dbms/src/Functions/FunctionsRound.h | 15 +++------------ dbms/src/Functions/FunctionsString.cpp | 12 ++++-------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/dbms/src/Functions/FunctionsRound.h b/dbms/src/Functions/FunctionsRound.h index 62f8ddf79d0..356d7f68cda 100644 --- a/dbms/src/Functions/FunctionsRound.h +++ b/dbms/src/Functions/FunctionsRound.h @@ -1126,18 +1126,6 @@ struct TiDBDecimalRoundInfo , output_prec(getDecimalPrecision(output_type, 0)) , output_scale(getDecimalScale(output_type, 0)) {} - - TiDBDecimalRoundInfo(const FracType & input_prec_, const FracType & input_scale_) - : input_prec(input_prec_) - , input_scale(input_scale_) - , input_int_prec(input_prec_ - input_scale_) - {} - - void setOutputPrecAndScale(const FracType & output_prec_, const FracType & output_scale_) - { - output_prec = output_prec_; - output_scale = output_scale_; - } }; template @@ -1194,6 +1182,9 @@ struct TiDBDecimalRound auto scaled_value = static_cast(absolute_value); + if (difference < 0) + scaled_value *= PowForOutput::result[-difference]; + // check overflow and construct result. if (scaled_value > DecimalMaxValue::get(info.output_prec)) throw TiFlashException("Data truncated", Errors::Decimal::Overflow); diff --git a/dbms/src/Functions/FunctionsString.cpp b/dbms/src/Functions/FunctionsString.cpp index 50db303e7c3..d6330ff62f8 100644 --- a/dbms/src/Functions/FunctionsString.cpp +++ b/dbms/src/Functions/FunctionsString.cpp @@ -4574,10 +4574,8 @@ class FormatImpl : public IFunction using NumberColVec = std::conditional_t, ColumnDecimal, ColumnVector>; const auto * number_raw = block.getByPosition(arguments[0]).column.get(); - auto input_prec = getDecimalPrecision(number_type, 0); - auto input_scale = getDecimalScale(number_type, 0); - - TiDBDecimalRoundInfo info{input_prec, input_scale}; + TiDBDecimalRoundInfo info{number_type, number_type}; + info.output_prec = info.output_prec < 65 ? info.output_prec + 1 : 65; return getPrecisionType(precision_base_type, [&](const auto & precision_type, bool) { using PrecisionType = std::decay_t; @@ -4595,7 +4593,6 @@ class FormatImpl : public IFunction for (size_t i = 0; i != val_num; ++i) { size_t max_num_decimals = getMaxNumDecimals(precision_array[i]); - info.setOutputPrecAndScale(input_prec, max_num_decimals); format(const_number, max_num_decimals, info, col_res->getChars(), col_res->getOffsets()); } } @@ -4607,7 +4604,6 @@ class FormatImpl : public IFunction if (const auto * col1_const = checkAndGetColumnConst(precision_raw)) { size_t max_num_decimals = getMaxNumDecimals(col1_const->template getValue()); - info.setOutputPrecAndScale(input_prec, max_num_decimals); for (const auto & number : col0_column->getData()) format(number, max_num_decimals, info, col_res->getChars(), col_res->getOffsets()); } @@ -4618,7 +4614,6 @@ class FormatImpl : public IFunction for (size_t i = 0; i != val_num; ++i) { size_t max_num_decimals = getMaxNumDecimals(precision_array[i]); - info.setOutputPrecAndScale(input_prec, max_num_decimals); format(number_array[i], max_num_decimals, info, col_res->getChars(), col_res->getOffsets()); } } @@ -4730,10 +4725,11 @@ class FormatImpl : public IFunction static void format( T number, size_t max_num_decimals, - const TiDBDecimalRoundInfo & info, + TiDBDecimalRoundInfo info, ColumnString::Chars_t & res_data, ColumnString::Offsets & res_offsets) { + info.output_scale = std::min(max_num_decimals, static_cast(info.input_scale)); auto round_number = round(number, max_num_decimals, info); std::string round_number_str = number2Str(round_number, info); std::string buffer = Format::apply(round_number_str, max_num_decimals); From 50f459867662ee62f17e8cff015c3ab119958ba9 Mon Sep 17 00:00:00 2001 From: xzhangxian1008 Date: Sat, 9 Jul 2022 17:19:24 +0800 Subject: [PATCH 09/11] update --- dbms/src/Functions/FunctionsString.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Functions/FunctionsString.cpp b/dbms/src/Functions/FunctionsString.cpp index d6330ff62f8..7986e291cc9 100644 --- a/dbms/src/Functions/FunctionsString.cpp +++ b/dbms/src/Functions/FunctionsString.cpp @@ -4702,7 +4702,7 @@ class FormatImpl : public IFunction static std::string number2Str(T number, const TiDBDecimalRoundInfo & info [[maybe_unused]]) { if constexpr (IsDecimal) - return number.toString(std::min(info.input_scale, info.output_scale)); + return number.toString(info.output_scale); else { static_assert(std::is_floating_point_v || std::is_integral_v); From d6e8f15e144a94be88cd41e6b355c6f6430df635 Mon Sep 17 00:00:00 2001 From: xzhangxian1008 Date: Mon, 11 Jul 2022 11:39:17 +0800 Subject: [PATCH 10/11] udpate --- dbms/src/Functions/FunctionsString.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Functions/FunctionsString.cpp b/dbms/src/Functions/FunctionsString.cpp index 7986e291cc9..76022b983ad 100644 --- a/dbms/src/Functions/FunctionsString.cpp +++ b/dbms/src/Functions/FunctionsString.cpp @@ -4725,7 +4725,7 @@ class FormatImpl : public IFunction static void format( T number, size_t max_num_decimals, - TiDBDecimalRoundInfo info, + TiDBDecimalRoundInfo & info, ColumnString::Chars_t & res_data, ColumnString::Offsets & res_offsets) { From aeab46a5575657507643438c700151f10c895948 Mon Sep 17 00:00:00 2001 From: xzhangxian1008 Date: Mon, 11 Jul 2022 14:05:06 +0800 Subject: [PATCH 11/11] add fullstack test --- tests/fullstack-test/expr/format.test | 49 +++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tests/fullstack-test/expr/format.test b/tests/fullstack-test/expr/format.test index 8cea75d6914..719e30c974d 100644 --- a/tests/fullstack-test/expr/format.test +++ b/tests/fullstack-test/expr/format.test @@ -44,3 +44,52 @@ int_val 1,234.000 mysql> drop table if exists test.t + +mysql> create table test.t(id int, value decimal(65,4)) +mysql> alter table test.t set tiflash replica 1 +mysql> insert into test.t values(1,9999999999999999999999999999999999999999999999999999999999999.9999) + +func> wait_table test t + +mysql> set tidb_enforce_mpp=1; set tidb_isolation_read_engines='tiflash'; select format(value,-3) as result from test.t +result +10,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 + +mysql> set tidb_enforce_mpp=1; set tidb_isolation_read_engines='tiflash'; select format(value,0) as result from test.t +result +10,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 + +mysql> set tidb_enforce_mpp=1; set tidb_isolation_read_engines='tiflash'; select format(value,3) as result from test.t +result +10,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000.000 + +mysql> set tidb_enforce_mpp=1; set tidb_isolation_read_engines='tiflash'; select format(value,10) as result from test.t +result +9,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999.9999000000 + + +mysql> drop table if exists test.t + +mysql> create table test.t(id int, value decimal(7,4)) +mysql> alter table test.t set tiflash replica 1 +mysql> insert into test.t values(1,999.9999) + +func> wait_table test t + +mysql> set tidb_enforce_mpp=1; set tidb_isolation_read_engines='tiflash'; select format(value,-2) as result from test.t +result +1,000 + +mysql> set tidb_enforce_mpp=1; set tidb_isolation_read_engines='tiflash'; select format(value,0) as result from test.t +result +1,000 + +mysql> set tidb_enforce_mpp=1; set tidb_isolation_read_engines='tiflash'; select format(value,2) as result from test.t +result +1,000.00 + +mysql> set tidb_enforce_mpp=1; set tidb_isolation_read_engines='tiflash'; select format(value,10) as result from test.t +result +999.9999000000 + +mysql> drop table if exists test.t