Skip to content

Commit 5a66534

Browse files
authored
expression: fix wrong result when convert float to unsigned (#53590) (#53611)
close #41736
1 parent b3369c9 commit 5a66534

File tree

4 files changed

+53
-1
lines changed

4 files changed

+53
-1
lines changed

pkg/expression/builtin_compare.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,6 +1431,13 @@ func RefineComparedConstant(ctx sessionctx.Context, targetFieldType types.FieldT
14311431
targetFieldType = *types.NewFieldType(mysql.TypeLonglong)
14321432
}
14331433
var intDatum types.Datum
1434+
1435+
// To make sure return zero when underflow happens.
1436+
oriFlag := sc.IsRefineComparedConstant
1437+
sc.IsRefineComparedConstant = true
1438+
defer func() {
1439+
sc.IsRefineComparedConstant = oriFlag
1440+
}()
14341441
intDatum, err = dt.ConvertTo(sc, &targetFieldType)
14351442
if err != nil {
14361443
if terror.ErrorEqual(err, types.ErrOverflow) {

pkg/sessionctx/stmtctx/stmtctx.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ type StatementContext struct {
166166
// IsDDLJobInQueue is used to mark whether the DDL job is put into the queue.
167167
// If IsDDLJobInQueue is true, it means the DDL job is in the queue of storage, and it can be handled by the DDL worker.
168168
IsDDLJobInQueue bool
169+
IsRefineComparedConstant bool
169170
DDLJobID int64
170171
InInsertStmt bool
171172
InUpdateStmt bool
@@ -1167,7 +1168,7 @@ func (sc *StatementContext) GetExecDetails() execdetails.ExecDetails {
11671168
// This is the case for `insert`, `update`, `alter table`, `create table` and `load data infile` statements, when not in strict SQL mode.
11681169
// see https://dev.mysql.com/doc/refman/5.7/en/out-of-range-and-overflow.html
11691170
func (sc *StatementContext) ShouldClipToZero() bool {
1170-
return sc.InInsertStmt || sc.InLoadDataStmt || sc.InUpdateStmt || sc.InCreateOrAlterStmt || sc.IsDDLJobInQueue
1171+
return sc.InInsertStmt || sc.InLoadDataStmt || sc.InUpdateStmt || sc.InCreateOrAlterStmt || sc.IsDDLJobInQueue || sc.IsRefineComparedConstant
11711172
}
11721173

11731174
// ShouldIgnoreOverflowError indicates whether we should ignore the error when type conversion overflows,

tests/integrationtest/r/expression/cast.result

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,33 @@ select null as a union all select 'a' as a;
9999
a
100100
NULL
101101
a
102+
drop table if exists t0;
103+
create table t0(c0 tinyint(1) unsigned not null );
104+
insert into t0 values (1);
105+
select * from t0 where case 0 when t0.c0 > -1.194192591e9 then null else 1 end;
106+
c0
107+
1
108+
select t0.c0 > -1.194192591e9 from t0;
109+
t0.c0 > -1.194192591e9
110+
1
111+
select t0.c0 < -1.194192591e9 from t0;
112+
t0.c0 < -1.194192591e9
113+
0
114+
select -1.194192591e9 > t0.c0 from t0;
115+
-1.194192591e9 > t0.c0
116+
0
117+
select -1.194192591e9 < t0.c0 from t0;
118+
-1.194192591e9 < t0.c0
119+
1
120+
select t0.c0 > 1.194192591e9 from t0;
121+
t0.c0 > 1.194192591e9
122+
0
123+
select t0.c0 < 1.194192591e9 from t0;
124+
t0.c0 < 1.194192591e9
125+
1
126+
select 1.194192591e9 > t0.c0 from t0;
127+
1.194192591e9 > t0.c0
128+
1
129+
select 1.194192591e9 < t0.c0 from t0;
130+
1.194192591e9 < t0.c0
131+
0

tests/integrationtest/t/expression/cast.test

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,17 @@ select cast('61qw' as decimal);
6060
explain select null as a union all select 'a' as a;
6161
--sorted_result
6262
select null as a union all select 'a' as a;
63+
64+
# TestNegFloatConvertToUnsigned
65+
drop table if exists t0;
66+
create table t0(c0 tinyint(1) unsigned not null );
67+
insert into t0 values (1);
68+
select * from t0 where case 0 when t0.c0 > -1.194192591e9 then null else 1 end;
69+
select t0.c0 > -1.194192591e9 from t0;
70+
select t0.c0 < -1.194192591e9 from t0;
71+
select -1.194192591e9 > t0.c0 from t0;
72+
select -1.194192591e9 < t0.c0 from t0;
73+
select t0.c0 > 1.194192591e9 from t0;
74+
select t0.c0 < 1.194192591e9 from t0;
75+
select 1.194192591e9 > t0.c0 from t0;
76+
select 1.194192591e9 < t0.c0 from t0;

0 commit comments

Comments
 (0)