From 9b95144e477de06f876572dabf6b41de98d6f2fd Mon Sep 17 00:00:00 2001 From: Ti Chi Robot Date: Wed, 13 Apr 2022 21:54:35 +0800 Subject: [PATCH] Fix cast datetime to decimal wrong result bug (#4152) (#4158) close pingcap/tiflash#4151 --- dbms/src/Functions/FunctionsTiDBConversion.h | 6 ++--- .../fullstack-test/expr/cast_as_decimal.test | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/dbms/src/Functions/FunctionsTiDBConversion.h b/dbms/src/Functions/FunctionsTiDBConversion.h index 2dba259f691..a1a32c9ac54 100644 --- a/dbms/src/Functions/FunctionsTiDBConversion.h +++ b/dbms/src/Functions/FunctionsTiDBConversion.h @@ -816,11 +816,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 index b244323015c..2541c97fc08 100644 --- a/tests/fullstack-test/expr/cast_as_decimal.test +++ b/tests/fullstack-test/expr/cast_as_decimal.test @@ -1,3 +1,27 @@ +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 | ++------------------------------------+ + mysql> drop table if exists test.t1; mysql> create table test.t1(c1 int); mysql> insert into test.t1 values(9999), (-9999), (99), (-99); @@ -15,3 +39,4 @@ cast(c1 as decimal(2, 2)) -0.99 0.99 0.99 +