diff --git a/expression/builtin_compare.go b/expression/builtin_compare.go index e699bd2d06db1..ded05100747e2 100644 --- a/expression/builtin_compare.go +++ b/expression/builtin_compare.go @@ -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) { diff --git a/sessionctx/stmtctx/stmtctx.go b/sessionctx/stmtctx/stmtctx.go index fc6c86fc11e3a..8e4b8813c9372 100644 --- a/sessionctx/stmtctx/stmtctx.go +++ b/sessionctx/stmtctx/stmtctx.go @@ -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 @@ -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, diff --git a/tests/integrationtest/r/expression/cast.result b/tests/integrationtest/r/expression/cast.result new file mode 100644 index 0000000000000..c7938cb727e72 --- /dev/null +++ b/tests/integrationtest/r/expression/cast.result @@ -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 diff --git a/tests/integrationtest/t/expression/cast.test b/tests/integrationtest/t/expression/cast.test new file mode 100644 index 0000000000000..6876072d60365 --- /dev/null +++ b/tests/integrationtest/t/expression/cast.test @@ -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;