Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

planner: support the plan cache aware of bindings #30169

Merged
merged 28 commits into from
Dec 16, 2021
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6bb0f22
planner: support the plan cache aware of bindings
Reminiscent Nov 26, 2021
2964adb
fix ut and add more comments
Reminiscent Nov 29, 2021
539630e
Merge branch 'master' of github.com:pingcap/tidb into addBinding2PC
Reminiscent Nov 29, 2021
8fd57a7
fix ut
Reminiscent Nov 29, 2021
d84aace
Merge branch 'master' of github.com:pingcap/tidb into addBinding2PC
Reminiscent Nov 29, 2021
06093d3
Merge branch 'master' of github.com:pingcap/tidb into addBinding2PC
Reminiscent Dec 1, 2021
8f66e45
revert the change for batchPointGet
Reminiscent Dec 2, 2021
82f75d1
Merge branch 'master' of github.com:pingcap/tidb into addBinding2PC
Reminiscent Dec 2, 2021
ff7a310
fix ut
Reminiscent Dec 2, 2021
c4afc5c
fix ut
Reminiscent Dec 2, 2021
a5222cb
add more test cases
Reminiscent Dec 2, 2021
a0d5b3c
Merge branch 'master' of github.com:pingcap/tidb into addBinding2PC
Reminiscent Dec 2, 2021
e41abc0
Merge branch 'master' into addBinding2PC
Reminiscent Dec 2, 2021
1eecc3c
Merge branch 'master' of github.com:pingcap/tidb into addBinding2PC
Reminiscent Dec 3, 2021
bbf9a9d
add more error messages
Reminiscent Dec 3, 2021
b369d96
Merge remote-tracking branch 'origin/addBinding2PC' into addBinding2PC
Reminiscent Dec 3, 2021
d7737fb
Merge branch 'master' into addBinding2PC
Reminiscent Dec 3, 2021
ec376a9
Merge branch 'master' of github.com:pingcap/tidb into addBinding2PC
Reminiscent Dec 3, 2021
fbc247a
Merge remote-tracking branch 'origin/addBinding2PC' into addBinding2PC
Reminiscent Dec 3, 2021
d3ec401
fix ut
Reminiscent Dec 3, 2021
41d8169
fix ut
Reminiscent Dec 3, 2021
1969c05
Merge branch 'master' of github.com:pingcap/tidb into addBinding2PC
Reminiscent Dec 13, 2021
56ac97c
address comments
Reminiscent Dec 13, 2021
db1b3bc
address comments
Reminiscent Dec 13, 2021
bbd9de8
add more test cases
Reminiscent Dec 14, 2021
aac62d9
Merge branch 'master' of github.com:pingcap/tidb into addBinding2PC
Reminiscent Dec 14, 2021
4548c6f
Merge branch 'master' into addBinding2PC
qw4990 Dec 15, 2021
cbe1c76
Merge branch 'master' into addBinding2PC
ti-chi-bot Dec 16, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
312 changes: 312 additions & 0 deletions bindinfo/bind_serial_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ package bindinfo_test

import (
"context"
"crypto/tls"
"fmt"
"strconv"
"testing"

"github.com/pingcap/tidb/bindinfo"
Expand All @@ -26,10 +28,320 @@ import (
"github.com/pingcap/tidb/parser/auth"
"github.com/pingcap/tidb/parser/model"
"github.com/pingcap/tidb/parser/terror"
plannercore "github.com/pingcap/tidb/planner/core"
"github.com/pingcap/tidb/session/txninfo"
"github.com/pingcap/tidb/testkit"
"github.com/pingcap/tidb/util"
"github.com/stretchr/testify/require"
)

// mockSessionManager is a mocked session manager which is used for test.
type mockSessionManager1 struct {
PS []*util.ProcessInfo
}

func (msm *mockSessionManager1) ShowTxnList() []*txninfo.TxnInfo {
return nil
}

// ShowProcessList implements the SessionManager.ShowProcessList interface.
func (msm *mockSessionManager1) ShowProcessList() map[uint64]*util.ProcessInfo {
ret := make(map[uint64]*util.ProcessInfo)
for _, item := range msm.PS {
ret[item.ID] = item
}
return ret
}

func (msm *mockSessionManager1) GetProcessInfo(id uint64) (*util.ProcessInfo, bool) {
for _, item := range msm.PS {
if item.ID == id {
return item, true
}
}
return &util.ProcessInfo{}, false
}

// Kill implements the SessionManager.Kill interface.
func (msm *mockSessionManager1) Kill(cid uint64, query bool) {
}

func (msm *mockSessionManager1) KillAllConnections() {
}

func (msm *mockSessionManager1) UpdateTLSConfig(cfg *tls.Config) {
}

func (msm *mockSessionManager1) ServerID() uint64 {
return 1
}

func TestPrepareCacheWithBinding(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("drop table if exists t1, t2")
tk.MustExec("create table t1(a int, b int, c int, key idx_b(b), key idx_c(c))")
tk.MustExec("create table t2(a int, b int, c int, key idx_b(b), key idx_c(c))")

// TestDMLSQLBind
tk.MustExec("prepare stmt1 from 'delete from t1 where b = 1 and c > 1';")
tk.MustExec("execute stmt1;")
require.Equal(t, "t1:idx_b", tk.Session().GetSessionVars().StmtCtx.IndexNames[0])
tkProcess := tk.Session().ShowProcess()
ps := []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res := tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.MustUseIndex4ExplainFor(res, "idx_b(b)"), res.Rows())
tk.MustExec("execute stmt1;")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

tk.MustExec("create global binding for delete from t1 where b = 1 and c > 1 using delete /*+ use_index(t1,idx_c) */ from t1 where b = 1 and c > 1")

tk.MustExec("execute stmt1;")
require.Equal(t, "t1:idx_c", tk.Session().GetSessionVars().StmtCtx.IndexNames[0])
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.MustUseIndex4ExplainFor(res, "idx_c(c)"), res.Rows())

tk.MustExec("prepare stmt2 from 'delete t1, t2 from t1 inner join t2 on t1.b = t2.b';")
tk.MustExec("execute stmt2;")
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.HasPlan4ExplainFor(res, "HashJoin"), res.Rows())
tk.MustExec("execute stmt2;")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

tk.MustExec("create global binding for delete t1, t2 from t1 inner join t2 on t1.b = t2.b using delete /*+ inl_join(t1) */ t1, t2 from t1 inner join t2 on t1.b = t2.b")

tk.MustExec("execute stmt2;")
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.HasPlan4ExplainFor(res, "IndexJoin"), res.Rows())

tk.MustExec("prepare stmt3 from 'update t1 set a = 1 where b = 1 and c > 1';")
tk.MustExec("execute stmt3;")
require.Equal(t, "t1:idx_b", tk.Session().GetSessionVars().StmtCtx.IndexNames[0])
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.MustUseIndex4ExplainFor(res, "idx_b(b)"), res.Rows())
tk.MustExec("execute stmt3;")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

tk.MustExec("create global binding for update t1 set a = 1 where b = 1 and c > 1 using update /*+ use_index(t1,idx_c) */ t1 set a = 1 where b = 1 and c > 1")

tk.MustExec("execute stmt3;")
require.Equal(t, "t1:idx_c", tk.Session().GetSessionVars().StmtCtx.IndexNames[0])
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.MustUseIndex4ExplainFor(res, "idx_c(c)"), res.Rows())

tk.MustExec("prepare stmt4 from 'update t1, t2 set t1.a = 1 where t1.b = t2.b';")
tk.MustExec("execute stmt4;")
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.HasPlan4ExplainFor(res, "HashJoin"), res.Rows())
tk.MustExec("execute stmt4;")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

tk.MustExec("create global binding for update t1, t2 set t1.a = 1 where t1.b = t2.b using update /*+ inl_join(t1) */ t1, t2 set t1.a = 1 where t1.b = t2.b")

tk.MustExec("execute stmt4;")
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.HasPlan4ExplainFor(res, "IndexJoin"), res.Rows())

tk.MustExec("prepare stmt5 from 'insert into t1 select * from t2 where t2.b = 2 and t2.c > 2';")
tk.MustExec("execute stmt5;")
require.Equal(t, "t2:idx_b", tk.Session().GetSessionVars().StmtCtx.IndexNames[0])
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.MustUseIndex4ExplainFor(res, "idx_b(b)"), res.Rows())
tk.MustExec("execute stmt5;")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

tk.MustExec("create global binding for insert into t1 select * from t2 where t2.b = 1 and t2.c > 1 using insert /*+ use_index(t2,idx_c) */ into t1 select * from t2 where t2.b = 1 and t2.c > 1")

tk.MustExec("execute stmt5;")
require.Equal(t, "t2:idx_b", tk.Session().GetSessionVars().StmtCtx.IndexNames[0])
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.MustUseIndex4ExplainFor(res, "idx_b(b)"), res.Rows())

tk.MustExec("drop global binding for insert into t1 select * from t2 where t2.b = 1 and t2.c > 1")
tk.MustExec("create global binding for insert into t1 select * from t2 where t2.b = 1 and t2.c > 1 using insert into t1 select /*+ use_index(t2,idx_c) */ * from t2 where t2.b = 1 and t2.c > 1")

tk.MustExec("execute stmt5;")
require.Equal(t, "t2:idx_c", tk.Session().GetSessionVars().StmtCtx.IndexNames[0])
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.MustUseIndex4ExplainFor(res, "idx_c(c)"), res.Rows())

tk.MustExec("prepare stmt6 from 'replace into t1 select * from t2 where t2.b = 2 and t2.c > 2';")
tk.MustExec("execute stmt6;")
require.Equal(t, "t2:idx_b", tk.Session().GetSessionVars().StmtCtx.IndexNames[0])
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.MustUseIndex4ExplainFor(res, "idx_b(b)"), res.Rows())
tk.MustExec("execute stmt6;")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

tk.MustExec("create global binding for replace into t1 select * from t2 where t2.b = 1 and t2.c > 1 using replace into t1 select /*+ use_index(t2,idx_c) */ * from t2 where t2.b = 1 and t2.c > 1")

tk.MustExec("execute stmt6;")
require.Equal(t, "t2:idx_c", tk.Session().GetSessionVars().StmtCtx.IndexNames[0])
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.MustUseIndex4ExplainFor(res, "idx_c(c)"), res.Rows())

// TestExplain
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add one more test of using hints to control index selection in this section.

tk.MustExec("drop table if exists t1")
tk.MustExec("drop table if exists t2")
tk.MustExec("create table t1(id int)")
tk.MustExec("create table t2(id int)")

tk.MustExec("prepare stmt1 from 'SELECT * from t1,t2 where t1.id = t2.id';")
tk.MustExec("execute stmt1;")
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.HasPlan4ExplainFor(res, "HashJoin"))
tk.MustExec("execute stmt1;")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

tk.MustExec("prepare stmt2 from 'SELECT /*+ TIDB_SMJ(t1, t2) */ * from t1,t2 where t1.id = t2.id';")
tk.MustExec("execute stmt2;")
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.HasPlan4ExplainFor(res, "MergeJoin"))
tk.MustExec("execute stmt2;")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

tk.MustExec("create global binding for SELECT * from t1,t2 where t1.id = t2.id using SELECT /*+ TIDB_SMJ(t1, t2) */ * from t1,t2 where t1.id = t2.id")

tk.MustExec("execute stmt1;")
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.HasPlan4ExplainFor(res, "MergeJoin"))

tk.MustExec("drop global binding for SELECT * from t1,t2 where t1.id = t2.id")

tk.MustExec("create index index_id on t1(id)")
tk.MustExec("prepare stmt1 from 'SELECT * from t1 use index(index_id)';")
tk.MustExec("execute stmt1;")
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.HasPlan4ExplainFor(res, "IndexReader"))
tk.MustExec("execute stmt1;")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

tk.MustExec("create global binding for SELECT * from t1 using SELECT * from t1 ignore index(index_id)")
tk.MustExec("execute stmt1;")
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.False(t, tk.HasPlan4ExplainFor(res, "IndexReader"))
tk.MustExec("execute stmt1;")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

// Add test for SetOprStmt
tk.MustExec("prepare stmt1 from 'SELECT * from t1 union SELECT * from t1';")
tk.MustExec("execute stmt1;")
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.False(t, tk.HasPlan4ExplainFor(res, "IndexReader"))
tk.MustExec("execute stmt1;")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

tk.MustExec("prepare stmt2 from 'SELECT * from t1 use index(index_id) union SELECT * from t1';")
tk.MustExec("execute stmt2;")
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.HasPlan4ExplainFor(res, "IndexReader"))
tk.MustExec("execute stmt2;")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

tk.MustExec("create global binding for SELECT * from t1 union SELECT * from t1 using SELECT * from t1 use index(index_id) union SELECT * from t1")

tk.MustExec("execute stmt1;")
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.HasPlan4ExplainFor(res, "IndexReader"))

tk.MustExec("drop global binding for SELECT * from t1 union SELECT * from t1")

// TestBindingSymbolList
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int, b int, INDEX ia (a), INDEX ib (b));")
tk.MustExec("insert into t value(1, 1);")
tk.MustExec("prepare stmt1 from 'select a, b from t where a = 3 limit 1, 100';")
tk.MustExec("execute stmt1;")
require.Equal(t, "t:ia", tk.Session().GetSessionVars().StmtCtx.IndexNames[0])
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.MustUseIndex4ExplainFor(res, "ia(a)"), res.Rows())
tk.MustExec("execute stmt1;")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))

tk.MustExec(`create global binding for select a, b from t where a = 1 limit 0, 1 using select a, b from t use index (ib) where a = 1 limit 0, 1`)

// after binding
tk.MustExec("execute stmt1;")
require.Equal(t, "t:ib", tk.Session().GetSessionVars().StmtCtx.IndexNames[0])
tkProcess = tk.Session().ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Session().SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
require.True(t, tk.MustUseIndex4ExplainFor(res, "ib(b)"), res.Rows())
}

func TestExplain(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()
Expand Down
14 changes: 9 additions & 5 deletions executor/explainfor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1124,16 +1124,20 @@ func (s *testPrepareSerialSuite) TestSPM4PlanCache(c *C) {
tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1"))

tk.MustQuery("execute stmt;").Check(testkit.Rows())
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
// The bindSQL has changed, the previous cache is invalid.
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
tk.MustQuery("execute stmt;").Check(testkit.Rows())
tkProcess = tk.Se.ShowProcess()
ps = []*util.ProcessInfo{tkProcess}
tk.Se.SetSessionManager(&mockSessionManager1{PS: ps})
res = tk.MustQuery("explain for connection " + strconv.FormatUint(tkProcess.ID, 10))
// The binding does not take effect for caches that have been cached.
c.Assert(res.Rows()[0][0], Matches, ".*TableReader.*")
c.Assert(res.Rows()[1][0], Matches, ".*TableFullScan.*")
tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("0"))
// We can use the new binding.
c.Assert(res.Rows()[0][0], Matches, ".*IndexReader.*")
c.Assert(res.Rows()[1][0], Matches, ".*IndexFullScan.*")
tk.MustQuery("execute stmt;").Check(testkit.Rows())
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("1"))
tk.MustQuery("execute stmt;").Check(testkit.Rows())
tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1"))

tk.MustExec("delete from mysql.bind_info where default_db='test';")
tk.MustExec("admin reload bindings;")
Expand Down
3 changes: 2 additions & 1 deletion executor/prepared.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,9 @@ func (e *DeallocateExec) Next(ctx context.Context, req *chunk.Chunk) error {
prepared := preparedObj.PreparedAst
delete(vars.PreparedStmtNameToID, e.Name)
if plannercore.PreparedPlanCacheEnabled() {
bindSQL := planner.GetBindSQL4PlanCache(e.ctx, prepared.Stmt)
e.ctx.PreparedPlanCache().Delete(plannercore.NewPSTMTPlanCacheKey(
vars, id, prepared.SchemaVersion,
vars, id, prepared.SchemaVersion, bindSQL,
))
}
vars.RemovePreparedStmt(id)
Expand Down
Loading