diff --git a/planner/core/integration_test.go b/planner/core/integration_test.go index d330ee6f22e0d..ac0d0021f2484 100644 --- a/planner/core/integration_test.go +++ b/planner/core/integration_test.go @@ -3628,6 +3628,28 @@ func (s *testIntegrationSuite) TestIssue26719(c *C) { tk.MustExec(`rollback`) } +func (s *testIntegrationSuite) TestIssue32428(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("create table `t1` (`a` enum('aa') DEFAULT NULL, KEY `k` (`a`))") + tk.MustExec("insert into t1 values('aa')") + tk.MustExec("insert into t1 values(null)") + tk.MustQuery("select a from t1 where a<=>'aa'").Check(testkit.Rows("aa")) + tk.MustQuery("select a from t1 where a<=>null").Check(testkit.Rows("")) + + tk.MustExec(`CREATE TABLE IDT_MULTI15860STROBJSTROBJ ( + COL1 enum('aa') DEFAULT NULL, + COL2 int(41) DEFAULT NULL, + COL3 year(4) DEFAULT NULL, + KEY U_M_COL4 (COL1,COL2), + KEY U_M_COL5 (COL3,COL2))`) + tk.MustExec(`insert into IDT_MULTI15860STROBJSTROBJ values("aa", 1013610488, 1982)`) + tk.MustQuery(`SELECT * FROM IDT_MULTI15860STROBJSTROBJ t1 RIGHT JOIN IDT_MULTI15860STROBJSTROBJ t2 ON t1.col1 <=> t2.col1 where t1.col1 is null and t2.col1 = "aa"`).Check(testkit.Rows()) // empty result + tk.MustExec(`prepare stmt from "SELECT * FROM IDT_MULTI15860STROBJSTROBJ t1 RIGHT JOIN IDT_MULTI15860STROBJSTROBJ t2 ON t1.col1 <=> t2.col1 where t1.col1 is null and t2.col1 = ?"`) + tk.MustExec(`set @a="aa"`) + tk.MustQuery(`execute stmt using @a`).Check(testkit.Rows()) // empty result +} + func (s *testIntegrationSerialSuite) TestPushDownProjectionForTiFlash(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") diff --git a/planner/core/prepare_test.go b/planner/core/prepare_test.go index 92c8e6ea969b9..f725f60eb8e30 100644 --- a/planner/core/prepare_test.go +++ b/planner/core/prepare_test.go @@ -2110,8 +2110,7 @@ func TestIssue30100(t *testing.T) { tk.MustExec("set @a=0;") tk.MustQuery("execute stmt using @a").Check(testkit.Rows()) tk.MustQuery("execute stmt using @a").Check(testkit.Rows()) - // If the plan contains the tableDual, it can not be cached. - tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) } func TestPartitionTable(t *testing.T) { diff --git a/util/ranger/points.go b/util/ranger/points.go index 3633c15690634..8b2fcf52fdf0a 100644 --- a/util/ranger/points.go +++ b/util/ranger/points.go @@ -458,6 +458,10 @@ func handleEnumFromBinOp(sc *stmtctx.StatementContext, ft *types.FieldType, val res = append(res, &point{value: d, excl: false, start: false}) } + if op == ast.NullEQ && val.IsNull() { + res = append(res, &point{start: true}, &point{}) // null point + } + tmpEnum := types.Enum{} for i := 0; i <= len(ft.Elems); i++ { if i == 0 { @@ -486,7 +490,7 @@ func handleEnumFromBinOp(sc *stmtctx.StatementContext, ft *types.FieldType, val if v >= 0 { appendPointFunc(d) } - case ast.EQ: + case ast.EQ, ast.NullEQ: if v == 0 { appendPointFunc(d) }