Skip to content

Commit

Permalink
expression: fix wrong result when convert float to unsigned (pingcap#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ti-chi-bot authored May 28, 2024
1 parent c2f973a commit cd1e029
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 1 deletion.
7 changes: 7 additions & 0 deletions expression/builtin_compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -1481,6 +1481,13 @@ func RefineComparedConstant(ctx sessionctx.Context, targetFieldType types.FieldT
targetFieldType = *types.NewFieldType(mysql.TypeLonglong)
}
var intDatum types.Datum

// To make sure return zero when underflow happens.
oriFlag := sc.IsRefineComparedConstant
sc.IsRefineComparedConstant = true
defer func() {
sc.IsRefineComparedConstant = oriFlag
}()
intDatum, err = dt.ConvertTo(sc, &targetFieldType)
if err != nil {
if terror.ErrorEqual(err, types.ErrOverflow) {
Expand Down
3 changes: 2 additions & 1 deletion sessionctx/stmtctx/stmtctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ type StatementContext struct {
// IsDDLJobInQueue is used to mark whether the DDL job is put into the queue.
// If IsDDLJobInQueue is true, it means the DDL job is in the queue of storage, and it can be handled by the DDL worker.
IsDDLJobInQueue bool
IsRefineComparedConstant bool
DDLJobID int64
InInsertStmt bool
InUpdateStmt bool
Expand Down Expand Up @@ -1097,7 +1098,7 @@ func (sc *StatementContext) GetExecDetails() execdetails.ExecDetails {
// This is the case for `insert`, `update`, `alter table`, `create table` and `load data infile` statements, when not in strict SQL mode.
// see https://dev.mysql.com/doc/refman/5.7/en/out-of-range-and-overflow.html
func (sc *StatementContext) ShouldClipToZero() bool {
return sc.InInsertStmt || sc.InLoadDataStmt || sc.InUpdateStmt || sc.InCreateOrAlterStmt || sc.IsDDLJobInQueue
return sc.InInsertStmt || sc.InLoadDataStmt || sc.InUpdateStmt || sc.InCreateOrAlterStmt || sc.IsDDLJobInQueue || sc.IsRefineComparedConstant
}

// ShouldIgnoreOverflowError indicates whether we should ignore the error when type conversion overflows,
Expand Down
30 changes: 30 additions & 0 deletions tests/integrationtest/r/expression/cast.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
drop table if exists t0;
create table t0(c0 tinyint(1) unsigned not null );
insert into t0 values (1);
select * from t0 where case 0 when t0.c0 > -1.194192591e9 then null else 1 end;
c0
1
select t0.c0 > -1.194192591e9 from t0;
t0.c0 > -1.194192591e9
1
select t0.c0 < -1.194192591e9 from t0;
t0.c0 < -1.194192591e9
0
select -1.194192591e9 > t0.c0 from t0;
-1.194192591e9 > t0.c0
0
select -1.194192591e9 < t0.c0 from t0;
-1.194192591e9 < t0.c0
1
select t0.c0 > 1.194192591e9 from t0;
t0.c0 > 1.194192591e9
0
select t0.c0 < 1.194192591e9 from t0;
t0.c0 < 1.194192591e9
1
select 1.194192591e9 > t0.c0 from t0;
1.194192591e9 > t0.c0
1
select 1.194192591e9 < t0.c0 from t0;
1.194192591e9 < t0.c0
0
13 changes: 13 additions & 0 deletions tests/integrationtest/t/expression/cast.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# TestNegFloatConvertToUnsigned
drop table if exists t0;
create table t0(c0 tinyint(1) unsigned not null );
insert into t0 values (1);
select * from t0 where case 0 when t0.c0 > -1.194192591e9 then null else 1 end;
select t0.c0 > -1.194192591e9 from t0;
select t0.c0 < -1.194192591e9 from t0;
select -1.194192591e9 > t0.c0 from t0;
select -1.194192591e9 < t0.c0 from t0;
select t0.c0 > 1.194192591e9 from t0;
select t0.c0 < 1.194192591e9 from t0;
select 1.194192591e9 > t0.c0 from t0;
select 1.194192591e9 < t0.c0 from t0;

0 comments on commit cd1e029

Please sign in to comment.