diff --git a/dbms/src/Functions/FunctionsTiDBConversion.h b/dbms/src/Functions/FunctionsTiDBConversion.h index af67521540e..abb88c2f638 100644 --- a/dbms/src/Functions/FunctionsTiDBConversion.h +++ b/dbms/src/Functions/FunctionsTiDBConversion.h @@ -1192,8 +1192,20 @@ struct TiDBConvertToDecimal /// cast enum/int/real as decimal const typename ColumnVector::Container & vec_from = col_from->getData(); - for (size_t i = 0; i < size; ++i) - vec_to[i] = toTiDBDecimal(vec_from[i], prec, scale, context); + if constexpr (std::is_integral_v) + { + /// cast enum/int as decimal + for (size_t i = 0; i < size; ++i) + vec_to[i] = toTiDBDecimal(vec_from[i], prec, scale, context); + } + else + { + /// cast real as decimal + static_assert(std::is_floating_point_v); + for (size_t i = 0; i < size; ++i) + // Always use Float64 to avoid overflow for vec_from[i] * 10^scale. + vec_to[i] = toTiDBDecimal(static_cast(vec_from[i]), prec, scale, context); + } } else { diff --git a/tests/fullstack-test/expr/cast_float_as_decimal.test b/tests/fullstack-test/expr/cast_float_as_decimal.test new file mode 100644 index 00000000000..8948e029a7d --- /dev/null +++ b/tests/fullstack-test/expr/cast_float_as_decimal.test @@ -0,0 +1,8 @@ +mysql> drop table if exists test.t1; +mysql> create table test.t1(c1 float); +mysql> insert into test.t1 values(3.40282e+37); +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(c1 as decimal(50, 2)) from test.t1; +cast(c1 as decimal(50, 2)) +34028199169636079590747176440761942016.00