Skip to content

Commit

Permalink
Fix wrong result of cast(float as decimal) when overflow happens (#4380
Browse files Browse the repository at this point in the history
…) (#4391)

close #3998
  • Loading branch information
ti-chi-bot authored Jun 15, 2022
1 parent d274700 commit 8ba626c
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
16 changes: 14 additions & 2 deletions dbms/src/Functions/FunctionsTiDBConversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -1170,8 +1170,20 @@ struct TiDBConvertToDecimal
/// cast int/real as decimal
const typename ColumnVector<FromFieldType>::Container & vec_from = col_from->getData();

for (size_t i = 0; i < size; ++i)
vec_to[i] = toTiDBDecimal<FromFieldType, ToFieldType>(vec_from[i], prec, scale, context);
if constexpr (std::is_integral_v<FromFieldType>)
{
/// cast enum/int as decimal
for (size_t i = 0; i < size; ++i)
vec_to[i] = toTiDBDecimal<FromFieldType, ToFieldType>(vec_from[i], prec, scale, context);
}
else
{
/// cast real as decimal
static_assert(std::is_floating_point_v<FromFieldType>);
for (size_t i = 0; i < size; ++i)
// Always use Float64 to avoid overflow for vec_from[i] * 10^scale.
vec_to[i] = toTiDBDecimal<Float64, ToFieldType>(static_cast<Float64>(vec_from[i]), prec, scale, context);
}
}
else
{
Expand Down
8 changes: 8 additions & 0 deletions tests/fullstack-test/expr/cast_float_as_decimal.test
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 8ba626c

Please sign in to comment.