diff --git a/expression/builtin_compare.go b/expression/builtin_compare.go index 4b2a220db33bb..b46db7522f2fe 100644 --- a/expression/builtin_compare.go +++ b/expression/builtin_compare.go @@ -1481,6 +1481,12 @@ 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 d5f19e8fe6dd5..981c6984ab20a 100644 --- a/sessionctx/stmtctx/stmtctx.go +++ b/sessionctx/stmtctx/stmtctx.go @@ -132,6 +132,9 @@ type StatementContext struct { SkipUTF8Check bool SkipASCIICheck bool SkipUTF8MB4Check bool + + IsRefineComparedConstant bool + // If the select statement was like 'select * from t as of timestamp ...' or in a stale read transaction // or is affected by the tidb_read_staleness session variable, then the statement will be makred as isStaleness // in stmtCtx @@ -775,7 +778,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;