From 96121e56f8c92ffdce06f3805e07bd6c60162b0c Mon Sep 17 00:00:00 2001 From: Yuanjia Zhang Date: Tue, 14 Feb 2023 22:36:01 +0800 Subject: [PATCH] planner: add more test cases for non-prepared plan cache (#41398) ref pingcap/tidb#36598 --- planner/core/plan_cache_test.go | 117 ++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/planner/core/plan_cache_test.go b/planner/core/plan_cache_test.go index 44f56721dd62c..87d0d75c71742 100644 --- a/planner/core/plan_cache_test.go +++ b/planner/core/plan_cache_test.go @@ -102,6 +102,123 @@ func TestIssue40296(t *testing.T) { tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) // unary operator '-' is not supported now. } +func TestNonPreparedPlanCacheSchemaChange(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`use test`) + tk.MustExec("create table t(a int)") + tk.MustExec("set tidb_enable_non_prepared_plan_cache=1") + + tk.MustExec("select * from t where a=1") + tk.MustExec("select * from t where a=1") + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + + tk.MustExec("alter table t add index idx_a(a)") + tk.MustExec("select * from t where a=1") + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) // cannot hit since the schema changed + tk.MustExec("select * from t where a=1") + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) +} + +func TestNonPreparedCacheWithPreparedCache(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`use test`) + tk.MustExec("create table t(a int)") + tk.MustExec("set tidb_enable_non_prepared_plan_cache=1") + + tk.MustExec(`prepare st from 'select * from t where a=1'`) + tk.MustExec(`execute st`) + tk.MustExec(`execute st`) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + + tk.MustExec(`select * from t where a=1`) // cannot hit since these 2 plan cache are separated + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) + tk.MustExec(`select * from t where a=1`) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) +} + +func TestNonPreparedPlanCacheSwitch(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`use test`) + tk.MustExec("create table t(a int)") + tk.MustExec("set tidb_enable_non_prepared_plan_cache=1") + + tk.MustExec(`select * from t where a=1`) + tk.MustExec(`select * from t where a=1`) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustExec("set tidb_enable_non_prepared_plan_cache=0") + tk.MustExec(`select * from t where a=1`) // the session-level switch can take effect in real time + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) +} + +func TestNonPreparedPlanCacheSQLMode(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`use test`) + tk.MustExec("create table t(a int)") + tk.MustExec("set tidb_enable_non_prepared_plan_cache=1") + + tk.MustExec(`select * from t where a=1`) + tk.MustExec(`select * from t where a=1`) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustExec("set @@sql_mode=''") // cannot hit since sql-mode changed + tk.MustExec(`select * from t where a=1`) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) + tk.MustExec(`select * from t where a=1`) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) +} + +func TestNonPreparedPlanCacheStats(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`use test`) + tk.MustExec("create table t(a int)") + tk.MustExec("insert into t values (2)") + tk.MustExec("set tidb_enable_non_prepared_plan_cache=1") + + tk.MustExec(`select * from t where a=1`) + tk.MustExec(`select * from t where a=1`) + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustExec("analyze table t") + tk.MustExec(`select * from t where a=1`) // stats changes won't affect non-prep cache hit + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) +} + +func TestNonPreparedPlanCacheHints(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`use test`) + tk.MustExec("create table t(a int, index(a))") + tk.MustExec("set tidb_enable_non_prepared_plan_cache=1") + + tk.MustExec("select /*+ use_index(t, a) */ * from t where a=1") + tk.MustExec("select /*+ use_index(t, a) */ * from t where a=1") // cannot hit since it has a hint + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) + + tk.MustExec("select * from t where a=1") + tk.MustExec("select * from t where a=1") + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) +} + +func TestNonPreparedPlanCacheBinding(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`use test`) + tk.MustExec("create table t(a int, index(a))") + tk.MustExec("set tidb_enable_non_prepared_plan_cache=1") + + tk.MustExec("create binding for select * from t where a=1 using select /*+ use_index(t, a) */ * from t where a=1") + tk.MustExec("select * from t where a=1") + tk.MustExec("select * from t where a=1") + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) + tk.MustExec("drop binding for select * from t where a=1") + tk.MustExec("select * from t where a=1") + tk.MustExec("select * from t where a=1") + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) +} + func TestNonPreparedPlanCacheWithExplain(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store)