From 131c7845f4f427043e925a54d0e3407949fe10b8 Mon Sep 17 00:00:00 2001 From: guo-shaoge Date: Tue, 30 Mar 2021 20:53:24 +0800 Subject: [PATCH 1/2] cherry pick #23694 to release-4.0 Signed-off-by: ti-srebot --- expression/builtin_compare.go | 15 +++++++++++---- expression/builtin_compare_test.go | 2 +- expression/expression_test.go | 7 +++++-- expression/integration_test.go | 13 +++++++++++++ planner/core/cbo_test.go | 2 +- 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/expression/builtin_compare.go b/expression/builtin_compare.go index 72b71de7ac5ca..c8ec32abb8228 100644 --- a/expression/builtin_compare.go +++ b/expression/builtin_compare.go @@ -1344,8 +1344,13 @@ func (c *compareFunctionClass) refineArgs(ctx sessionctx.Context, args []Express // int non-constant [cmp] non-int constant if arg0IsInt && !arg0IsCon && !arg1IsInt && arg1IsCon { arg1, isExceptional = RefineComparedConstant(ctx, *arg0Type, arg1, c.op) - finalArg1 = arg1 - if isExceptional && arg1.GetType().EvalType() == types.ETInt { + // Why check not null flag + // eg: int_col > const_val(which is less than min_int32) + // If int_col got null, compare result cannot be true + if !isExceptional || (isExceptional && mysql.HasNotNullFlag(arg0Type.Flag)) { + finalArg1 = arg1 + } + if isExceptional && arg1.GetType().EvalType() == types.ETInt && mysql.HasNotNullFlag(arg0Type.Flag) { // Judge it is inf or -inf // For int: // inf: 01111111 & 1 == 1 @@ -1363,8 +1368,10 @@ func (c *compareFunctionClass) refineArgs(ctx sessionctx.Context, args []Express // non-int constant [cmp] int non-constant if arg1IsInt && !arg1IsCon && !arg0IsInt && arg0IsCon { arg0, isExceptional = RefineComparedConstant(ctx, *arg1Type, arg0, symmetricOp[c.op]) - finalArg0 = arg0 - if isExceptional && arg0.GetType().EvalType() == types.ETInt { + if !isExceptional || (isExceptional && mysql.HasNotNullFlag(arg1Type.Flag)) { + finalArg0 = arg0 + } + if isExceptional && arg0.GetType().EvalType() == types.ETInt && mysql.HasNotNullFlag(arg1Type.Flag) { if arg0.Value.GetInt64()&1 == 1 { isNegativeInfinite = true } else { diff --git a/expression/builtin_compare_test.go b/expression/builtin_compare_test.go index f8b8e6f08843c..1e3908b856030 100644 --- a/expression/builtin_compare_test.go +++ b/expression/builtin_compare_test.go @@ -27,7 +27,7 @@ import ( ) func (s *testEvaluatorSuite) TestCompareFunctionWithRefine(c *C) { - tblInfo := newTestTableBuilder("").add("a", mysql.TypeLong).build() + tblInfo := newTestTableBuilder("").add("a", mysql.TypeLong, mysql.NotNullFlag).build() tests := []struct { exprStr string result string diff --git a/expression/expression_test.go b/expression/expression_test.go index 2ecdc12f465eb..40eed2c946207 100644 --- a/expression/expression_test.go +++ b/expression/expression_test.go @@ -35,7 +35,7 @@ func (s *testEvaluatorSuite) TestNewValuesFunc(c *C) { } func (s *testEvaluatorSuite) TestEvaluateExprWithNull(c *C) { - tblInfo := newTestTableBuilder("").add("col0", mysql.TypeLonglong).add("col1", mysql.TypeLonglong).build() + tblInfo := newTestTableBuilder("").add("col0", mysql.TypeLonglong, 0).add("col1", mysql.TypeLonglong, 0).build() schema := tableInfoToSchemaForTest(tblInfo) col0 := schema.Columns[0] col1 := schema.Columns[1] @@ -142,15 +142,17 @@ type testTableBuilder struct { tableName string columnNames []string tps []byte + flags []uint } func newTestTableBuilder(tableName string) *testTableBuilder { return &testTableBuilder{tableName: tableName} } -func (builder *testTableBuilder) add(name string, tp byte) *testTableBuilder { +func (builder *testTableBuilder) add(name string, tp byte, flag uint) *testTableBuilder { builder.columnNames = append(builder.columnNames, name) builder.tps = append(builder.tps, tp) + builder.flags = append(builder.flags, flag) return builder } @@ -165,6 +167,7 @@ func (builder *testTableBuilder) build() *model.TableInfo { fieldType := types.NewFieldType(tp) fieldType.Flen, fieldType.Decimal = mysql.GetDefaultFieldLengthAndDecimal(tp) fieldType.Charset, fieldType.Collate = types.DefaultCharsetForType(tp) + fieldType.Flag = builder.flags[i] ti.Columns = append(ti.Columns, &model.ColumnInfo{ ID: int64(i + 1), Name: model.NewCIStr(colName), diff --git a/expression/integration_test.go b/expression/integration_test.go index 614f06a51b838..c528fa41569db 100755 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -8068,6 +8068,19 @@ func (s *testIntegrationSerialSuite) TestIssue19116(c *C) { collate.SetNewCollationEnabledForTest(true) defer collate.SetNewCollationEnabledForTest(false) +<<<<<<< HEAD +======= +func (s *testIntegrationSuite) TestIssue23623(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t1;") + tk.MustExec("create table t1(c1 int);") + tk.MustExec("insert into t1 values(-2147483648), (-2147483648), (null);") + tk.MustQuery("select count(*) from t1 where c1 > (select sum(c1) from t1);").Check(testkit.Rows("2")) +} + +func (s *testIntegrationSuite) TestApproximatePercentile(c *C) { +>>>>>>> 3ed4a23b9... executor: refineArgs() bug fix when compare int with very small decimal (#23694) tk := testkit.NewTestKit(c, s.store) tk.MustExec("set names utf8mb4 collate utf8mb4_general_ci;") tk.MustQuery("select collation(concat(1 collate `binary`));").Check(testkit.Rows("binary")) diff --git a/planner/core/cbo_test.go b/planner/core/cbo_test.go index 3d42bcf1fc8b1..1cd6e4d0037c0 100644 --- a/planner/core/cbo_test.go +++ b/planner/core/cbo_test.go @@ -444,7 +444,7 @@ func (s *testAnalyzeSuite) TestPreparedNullParam(c *C) { testKit := testkit.NewTestKit(c, store) testKit.MustExec("use test") testKit.MustExec("drop table if exists t") - testKit.MustExec("create table t (id int, KEY id (id))") + testKit.MustExec("create table t (id int not null, KEY id (id))") testKit.MustExec("insert into t values (1), (2), (3)") sql := "select * from t where id = ?" From 39110a15b419272a2d2485f5a5d171d7a1e58a9e Mon Sep 17 00:00:00 2001 From: guo-shaoge Date: Tue, 30 Mar 2021 05:47:50 +0800 Subject: [PATCH 2/2] fix confilicts Signed-off-by: guo-shaoge --- expression/integration_test.go | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/expression/integration_test.go b/expression/integration_test.go index c528fa41569db..cc983deab44dd 100755 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -8068,19 +8068,6 @@ func (s *testIntegrationSerialSuite) TestIssue19116(c *C) { collate.SetNewCollationEnabledForTest(true) defer collate.SetNewCollationEnabledForTest(false) -<<<<<<< HEAD -======= -func (s *testIntegrationSuite) TestIssue23623(c *C) { - tk := testkit.NewTestKit(c, s.store) - tk.MustExec("use test") - tk.MustExec("drop table if exists t1;") - tk.MustExec("create table t1(c1 int);") - tk.MustExec("insert into t1 values(-2147483648), (-2147483648), (null);") - tk.MustQuery("select count(*) from t1 where c1 > (select sum(c1) from t1);").Check(testkit.Rows("2")) -} - -func (s *testIntegrationSuite) TestApproximatePercentile(c *C) { ->>>>>>> 3ed4a23b9... executor: refineArgs() bug fix when compare int with very small decimal (#23694) tk := testkit.NewTestKit(c, s.store) tk.MustExec("set names utf8mb4 collate utf8mb4_general_ci;") tk.MustQuery("select collation(concat(1 collate `binary`));").Check(testkit.Rows("binary")) @@ -8093,3 +8080,12 @@ func (s *testIntegrationSuite) TestApproximatePercentile(c *C) { tk.MustQuery("select coercibility(1);").Check(testkit.Rows("5")) tk.MustQuery("select coercibility(1=1);").Check(testkit.Rows("5")) } + +func (s *testIntegrationSuite) TestIssue23623(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t1;") + tk.MustExec("create table t1(c1 int);") + tk.MustExec("insert into t1 values(-2147483648), (-2147483648), (null);") + tk.MustQuery("select count(*) from t1 where c1 > (select sum(c1) from t1);").Check(testkit.Rows("2")) +}