From 5c0c626fc3a2727b9995bbf847748b481917844d Mon Sep 17 00:00:00 2001 From: Ti Chi Robot Date: Wed, 15 Jun 2022 23:22:34 +0800 Subject: [PATCH] Fix cast datetime to decimal wrong result bug (#4152) (#4156) close pingcap/tiflash#4151 --- dbms/src/Functions/FunctionsTiDBConversion.h | 6 ++--- .../fullstack-test/expr/cast_as_decimal.test | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 tests/fullstack-test/expr/cast_as_decimal.test diff --git a/dbms/src/Functions/FunctionsTiDBConversion.h b/dbms/src/Functions/FunctionsTiDBConversion.h index 2a1c912ec6d..2a3f40abbb9 100644 --- a/dbms/src/Functions/FunctionsTiDBConversion.h +++ b/dbms/src/Functions/FunctionsTiDBConversion.h @@ -809,11 +809,11 @@ struct TiDBConvertToDecimal template static U toTiDBDecimal(MyDateTime & date_time, PrecType prec, ScaleType scale, int fsp, const Context & context) { - UInt64 value_without_fsp = date_time.year * 10000000000ULL + date_time.month * 100000000ULL + date_time.day * 100000 - + date_time.hour * 1000 + date_time.minute * 100 + date_time.second; + UInt64 value_without_fsp = date_time.year * 10000000000ULL + date_time.month * 100000000ULL + date_time.day * 1000000ULL + + date_time.hour * 10000ULL + date_time.minute * 100 + date_time.second; if (fsp > 0) { - Int128 value = value_without_fsp * 1000000 + date_time.micro_second; + Int128 value = static_cast(value_without_fsp) * 1000000 + date_time.micro_second; Decimal128 decimal(value); return toTiDBDecimal(decimal, 6, prec, scale, context); } diff --git a/tests/fullstack-test/expr/cast_as_decimal.test b/tests/fullstack-test/expr/cast_as_decimal.test new file mode 100644 index 00000000000..f0985e3cad3 --- /dev/null +++ b/tests/fullstack-test/expr/cast_as_decimal.test @@ -0,0 +1,23 @@ +mysql> drop table if exists test.t1; +mysql> create table test.t1(c1 datetime(5)); +mysql> insert into test.t1 values('2022-10-10 10:10:10.12345'); +mysql> alter table test.t1 set tiflash replica 1; +func> wait_table test t1 +mysql> set @@tidb_isolation_read_engines='tiflash'; set @@tidb_enforce_mpp = 1; select cast(test.t1.c1 as decimal(16, 3)) from test.t1; ++------------------------------------+ +| cast(test.t1.c1 as decimal(16, 3)) | ++------------------------------------+ +| 9999999999999.999 | ++------------------------------------+ +mysql> set @@tidb_isolation_read_engines='tiflash'; set @@tidb_enforce_mpp = 1; select cast(test.t1.c1 as decimal(17, 3)) from test.t1; ++------------------------------------+ +| cast(test.t1.c1 as decimal(17, 3)) | ++------------------------------------+ +| 20221010101010.123 | ++------------------------------------+ +mysql> set @@tidb_isolation_read_engines='tiflash'; set @@tidb_enforce_mpp = 1; select cast(test.t1.c1 as decimal(18, 3)) from test.t1; ++------------------------------------+ +| cast(test.t1.c1 as decimal(18, 3)) | ++------------------------------------+ +| 20221010101010.123 | ++------------------------------------+