From 8b92c83f324bb98ec6ba7c3670f704a2ab2a1ade Mon Sep 17 00:00:00 2001 From: Yuanjia Zhang Date: Thu, 30 Mar 2023 16:40:55 +0800 Subject: [PATCH] planner: check the ignore-plan-cache hint in insert-stmt (#40080) (#42712) ref pingcap/tidb#39717, close pingcap/tidb#40079 --- executor/prepared_test.go | 23 +++++++++++++++++++++++ planner/core/cacheable_checker.go | 18 ++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/executor/prepared_test.go b/executor/prepared_test.go index d357ed15cdf58..375dc18210357 100644 --- a/executor/prepared_test.go +++ b/executor/prepared_test.go @@ -1204,6 +1204,29 @@ func TestPlanCacheOperators(t *testing.T) { } } +func TestIgnoreInsertStmt(t *testing.T) { + store, clean := testkit.CreateMockStore(t) + defer clean() + 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)") + + // ignore-hint in insert-stmt can work + tk.MustExec("prepare st from 'insert into t select * from t'") + tk.MustExec("execute st") + tk.MustExec("execute st") + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1")) + tk.MustExec("prepare st from 'insert /*+ ignore_plan_cache() */ into t select * from t'") + tk.MustExec("execute st") + tk.MustExec("execute st") + tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0")) +} + func TestIssue28782(t *testing.T) { store, clean := testkit.CreateMockStore(t) defer clean() diff --git a/planner/core/cacheable_checker.go b/planner/core/cacheable_checker.go index 90c0fcc3bbd83..c43d745f70f2e 100644 --- a/planner/core/cacheable_checker.go +++ b/planner/core/cacheable_checker.go @@ -87,6 +87,24 @@ func (checker *cacheableChecker) Enter(in ast.Node) (out ast.Node, skipChildren return in, true } } + case *ast.InsertStmt: + if node.Select == nil { + nRows := len(node.Lists) + nCols := 0 + if len(node.Lists) > 0 { // avoid index-out-of-range + nCols = len(node.Lists[0]) + } + if nRows*nCols > 200 { // to save memory + checker.cacheable = false + return in, true + } + } + for _, hints := range node.TableHints { + if hints.HintName.L == HintIgnorePlanCache { + checker.cacheable = false + return in, true + } + } case *ast.VariableExpr, *ast.ExistsSubqueryExpr, *ast.SubqueryExpr: checker.cacheable = false return in, true