diff --git a/executor/explainfor_test.go b/executor/explainfor_test.go index cc42d4b5c0107..246262ac0a9ef 100644 --- a/executor/explainfor_test.go +++ b/executor/explainfor_test.go @@ -958,7 +958,7 @@ func (s *testPrepareSerialSuite) TestIndexMerge4PlanCache(c *C) { tk.MustExec("set @a=9, @b=10, @c=11;") tk.MustQuery("execute stmt using @a, @a;").Check(testkit.Rows("10 10 10")) tk.MustQuery("execute stmt using @a, @c;").Check(testkit.Rows("10 10 10", "11 11 11")) - tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("0")) // a>=9 and a<=9 --> a=9 tk.MustQuery("execute stmt using @c, @a;").Check(testkit.Rows("10 10 10")) tk.MustQuery("select @@last_plan_from_cache;").Check(testkit.Rows("1")) diff --git a/executor/prepared_test.go b/executor/prepared_test.go index 176b4c6306020..3e1f8e8ef40fd 100644 --- a/executor/prepared_test.go +++ b/executor/prepared_test.go @@ -150,6 +150,37 @@ func TestPreparedStmtWithHint(t *testing.T) { require.Equal(t, int32(1), atomic.LoadInt32(&sm.killed)) } +func TestIssue38533(t *testing.T) { + store, dom, err := newStoreWithBootstrap() + require.NoError(t, err) + defer func() { + require.NoError(t, store.Close()) + dom.Close() + }() + + orgEnable := plannercore.PreparedPlanCacheEnabled() + defer func() { + plannercore.SetPreparedPlanCache(orgEnable) + }() + plannercore.SetPreparedPlanCache(true) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("create table t (a int, key (a))") + tk.MustExec(`prepare st from "select /*+ use_index(t, a) */ a from t where a=? and a=?"`) + tk.MustExec(`set @a=1`) + tk.MustExec(`execute st using @a, @a`) + tkProcess := tk.Session().ShowProcess() + ps := []*util.ProcessInfo{tkProcess} + tk.Session().SetSessionManager(&mockSessionManager1{PS: ps}) + plan := tk.MustQuery(fmt.Sprintf("explain for connection %d", tkProcess.ID)).Rows() + require.True(t, strings.Contains(plan[1][0].(string), "RangeScan")) // range-scan instead of full-scan + + tk.MustExec(`execute st using @a, @a`) + tk.MustExec(`execute st using @a, @a`) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) +} + func TestIssue29850(t *testing.T) { store, dom, err := newStoreWithBootstrap() require.NoError(t, err) diff --git a/planner/core/prepare_test.go b/planner/core/prepare_test.go index c737b9e070231..ef2465195808d 100644 --- a/planner/core/prepare_test.go +++ b/planner/core/prepare_test.go @@ -1521,7 +1521,7 @@ func (s *testPlanSerialSuite) TestIssue29303(c *C) { tk.MustQuery(`execute stmt using @a,@b,@c,@d`).Check(testkit.Rows()) tk.MustExec(`set @a="龂", @b="龂", @c="龂", @d="龂"`) tk.MustQuery(`execute stmt using @a,@b,@c,@d`).Check(testkit.Rows("� 龂 � 龂")) - tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("0")) + tk.MustQuery(`select @@last_plan_from_cache`).Check(testkit.Rows("1")) } func (s *testPlanSerialSuite) TestIssue28942(c *C) { @@ -2068,7 +2068,7 @@ func (s *testPlanSerialSuite) TestPlanCachePointGetAndTableDual(c *C) { tk.MustQuery("execute s1 using @a1, @b1, @b1").Check(testkit.Rows()) tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) tk.MustQuery("execute s1 using @a1, @a1, @b1").Check(testkit.Rows("0000 7777 1")) - tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) // c2>=9999 and c2<=9999 --> c2=9999 tk.MustExec("create table t2(c1 bigint(20) primary key, c2 varchar(20))") tk.MustExec("insert into t2 values(1,'7777')") @@ -2088,7 +2088,7 @@ func (s *testPlanSerialSuite) TestPlanCachePointGetAndTableDual(c *C) { tk.MustQuery("execute s3 using @a3,@a3").Check(testkit.Rows()) tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) tk.MustQuery("execute s3 using @a3,@b3").Check(testkit.Rows("2 1 1")) - tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) // c1>=1 and c1<=1 --> c1==1 tk.MustExec("prepare s3 from 'select /*+ use_index_merge(t3) */ * from t3 where (c1 >= ? and c1 <= ?) or c2 > 1'") tk.MustExec("set @a3=1,@b3=3") @@ -2105,7 +2105,7 @@ func (s *testPlanSerialSuite) TestPlanCachePointGetAndTableDual(c *C) { tk.MustQuery("execute s4 using @a4,@a4").Check(testkit.Rows()) tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) tk.MustQuery("execute s4 using @a4,@b4").Check(testkit.Rows("2 1 1")) - tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) tk.MustExec("prepare s4 from 'select /*+ use_index_merge(t4) */ * from t4 where (c1 >= ? and c1 <= ?) or c2 > 1'") tk.MustExec("set @a4=1,@b4=3") @@ -2198,7 +2198,7 @@ func (s *testPlanSerialSuite) TestIssue23671(c *C) { tk.MustQuery("execute s1 using @a, @b, @c").Check(testkit.Rows("1 1")) tk.MustExec("set @a=1, @b=1, @c=10") tk.MustQuery("execute s1 using @a, @b, @c").Check(testkit.Rows("1 1", "2 2")) - tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) } func (s *testPrepareSerialSuite) TestIssue29296(c *C) { diff --git a/util/ranger/detacher.go b/util/ranger/detacher.go index 51bf22e9b62c1..b2ac1075f285d 100644 --- a/util/ranger/detacher.go +++ b/util/ranger/detacher.go @@ -577,8 +577,8 @@ func ExtractEqAndInCondition(sctx sessionctx.Context, conditions []expression.Ex columnValues[i] = &valueInfo{mutable: true} } if expression.MaybeOverOptimized4PlanCache(sctx, conditions) { - // TODO: optimize it more elaborately, e.g. return [2 3, 2 3] as accesses for 'where a = 2 and b = 3 and c >= ? and c <= ?' - return nil, conditions, nil, nil, false + // `a=@x and a=@y` --> `a=@x if @x==@y` + sctx.GetSessionVars().StmtCtx.SkipPlanCache = true } } }