Skip to content

Commit

Permalink
This is an automated cherry-pick of #40256
Browse files Browse the repository at this point in the history
Signed-off-by: ti-chi-bot <[email protected]>
  • Loading branch information
qw4990 authored and ti-chi-bot committed Feb 14, 2023
1 parent 5fa25e8 commit 202fe31
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 13 deletions.
16 changes: 8 additions & 8 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3587,10 +3587,10 @@ func TestPointGetPreparedPlan(t *testing.T) {

pspk1Id, _, _, err := tk.Session().PrepareStmt("select * from t where a = ?")
require.NoError(t, err)
tk.Session().GetSessionVars().PreparedStmts[pspk1Id].(*plannercore.PlanCacheStmt).PreparedAst.UseCache = false
tk.Session().GetSessionVars().PreparedStmts[pspk1Id].(*plannercore.PlanCacheStmt).StmtCacheable = false
pspk2Id, _, _, err := tk.Session().PrepareStmt("select * from t where ? = a ")
require.NoError(t, err)
tk.Session().GetSessionVars().PreparedStmts[pspk2Id].(*plannercore.PlanCacheStmt).PreparedAst.UseCache = false
tk.Session().GetSessionVars().PreparedStmts[pspk2Id].(*plannercore.PlanCacheStmt).StmtCacheable = false

ctx := context.Background()
// first time plan generated
Expand Down Expand Up @@ -3630,7 +3630,7 @@ func TestPointGetPreparedPlan(t *testing.T) {
// unique index
psuk1Id, _, _, err := tk.Session().PrepareStmt("select * from t where b = ? ")
require.NoError(t, err)
tk.Session().GetSessionVars().PreparedStmts[psuk1Id].(*plannercore.PlanCacheStmt).PreparedAst.UseCache = false
tk.Session().GetSessionVars().PreparedStmts[psuk1Id].(*plannercore.PlanCacheStmt).StmtCacheable = false

rs, err = tk.Session().ExecutePreparedStmt(ctx, psuk1Id, expression.Args2Expressions4Test(1))
require.NoError(t, err)
Expand Down Expand Up @@ -3748,7 +3748,7 @@ func TestPointGetPreparedPlanWithCommitMode(t *testing.T) {

pspk1Id, _, _, err := tk1.Session().PrepareStmt("select * from t where a = ?")
require.NoError(t, err)
tk1.Session().GetSessionVars().PreparedStmts[pspk1Id].(*plannercore.PlanCacheStmt).PreparedAst.UseCache = false
tk1.Session().GetSessionVars().PreparedStmts[pspk1Id].(*plannercore.PlanCacheStmt).StmtCacheable = false

ctx := context.Background()
// first time plan generated
Expand Down Expand Up @@ -3814,11 +3814,11 @@ func TestPointUpdatePreparedPlan(t *testing.T) {

updateID1, pc, _, err := tk.Session().PrepareStmt(`update t set c = c + 1 where a = ?`)
require.NoError(t, err)
tk.Session().GetSessionVars().PreparedStmts[updateID1].(*plannercore.PlanCacheStmt).PreparedAst.UseCache = false
tk.Session().GetSessionVars().PreparedStmts[updateID1].(*plannercore.PlanCacheStmt).StmtCacheable = false
require.Equal(t, 1, pc)
updateID2, pc, _, err := tk.Session().PrepareStmt(`update t set c = c + 2 where ? = a`)
require.NoError(t, err)
tk.Session().GetSessionVars().PreparedStmts[updateID2].(*plannercore.PlanCacheStmt).PreparedAst.UseCache = false
tk.Session().GetSessionVars().PreparedStmts[updateID2].(*plannercore.PlanCacheStmt).StmtCacheable = false
require.Equal(t, 1, pc)

ctx := context.Background()
Expand Down Expand Up @@ -3853,7 +3853,7 @@ func TestPointUpdatePreparedPlan(t *testing.T) {
// unique index
updUkID1, _, _, err := tk.Session().PrepareStmt(`update t set c = c + 10 where b = ?`)
require.NoError(t, err)
tk.Session().GetSessionVars().PreparedStmts[updUkID1].(*plannercore.PlanCacheStmt).PreparedAst.UseCache = false
tk.Session().GetSessionVars().PreparedStmts[updUkID1].(*plannercore.PlanCacheStmt).StmtCacheable = false
rs, err = tk.Session().ExecutePreparedStmt(ctx, updUkID1, expression.Args2Expressions4Test(3))
require.Nil(t, rs)
require.NoError(t, err)
Expand Down Expand Up @@ -3922,7 +3922,7 @@ func TestPointUpdatePreparedPlanWithCommitMode(t *testing.T) {

ctx := context.Background()
updateID1, _, _, err := tk1.Session().PrepareStmt(`update t set c = c + 1 where a = ?`)
tk1.Session().GetSessionVars().PreparedStmts[updateID1].(*plannercore.PlanCacheStmt).PreparedAst.UseCache = false
tk1.Session().GetSessionVars().PreparedStmts[updateID1].(*plannercore.PlanCacheStmt).StmtCacheable = false
require.NoError(t, err)

// first time plan generated
Expand Down
1 change: 0 additions & 1 deletion parser/ast/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,6 @@ type Prepared struct {
StmtType string
Params []ParamMarkerExpr
SchemaVersion int64
UseCache bool
CachedPlan interface{}
CachedNames interface{}
}
Expand Down
22 changes: 20 additions & 2 deletions planner/core/plan_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,13 @@ func planCachePreprocess(ctx context.Context, sctx sessionctx.Context, isGeneral
// So we need to clear the current session's plan cache.
// And update lastUpdateTime to the newest one.
expiredTimeStamp4PC := domain.GetDomain(sctx).ExpiredTimeStamp4PC()
<<<<<<< HEAD
if stmtAst.UseCache && expiredTimeStamp4PC.Compare(vars.LastUpdateTime4PC) > 0 {
sctx.GetPlanCache(isGeneralPlanCache).DeleteAll()
=======
if stmt.StmtCacheable && expiredTimeStamp4PC.Compare(vars.LastUpdateTime4PC) > 0 {
sctx.GetPlanCache(isNonPrepared).DeleteAll()
>>>>>>> 5327d07afc7 (planner: refactor plan-cache UseCache flag (#40256))
stmtAst.CachedPlan = nil
vars.LastUpdateTime4PC = expiredTimeStamp4PC
}
Expand All @@ -123,7 +128,10 @@ func GetPlanFromSessionPlanCache(ctx context.Context, sctx sessionctx.Context,
sessVars := sctx.GetSessionVars()
stmtCtx := sessVars.StmtCtx
stmtAst := stmt.PreparedAst
stmtCtx.UseCache = stmtAst.UseCache
stmtCtx.UseCache = stmt.StmtCacheable
if !stmt.StmtCacheable {
stmtCtx.SetSkipPlanCache(errors.Errorf("skip plan-cache: %s", stmt.UncacheableReason))
}

var bindSQL string
var ignorePlanCache = false
Expand All @@ -132,7 +140,7 @@ func GetPlanFromSessionPlanCache(ctx context.Context, sctx sessionctx.Context,
// rebuild the plan. So we set this value in rc or for update read. In other cases, let it be 0.
var latestSchemaVersion int64

if stmtAst.UseCache {
if stmtCtx.UseCache {
bindSQL, ignorePlanCache = GetBindSQL4PlanCache(sctx, stmt)
if sctx.GetSessionVars().IsIsolation(ast.ReadCommitted) || stmt.ForUpdateRead {
// In Rc or ForUpdateRead, we should check if the information schema has been changed since
Expand All @@ -148,14 +156,24 @@ func GetPlanFromSessionPlanCache(ctx context.Context, sctx sessionctx.Context,

paramNum, paramTypes := parseParamTypes(sctx, params)

<<<<<<< HEAD
if stmtAst.UseCache && stmtAst.CachedPlan != nil && !ignorePlanCache { // for point query plan
if plan, names, ok, err := getPointQueryPlan(stmtAst, sessVars, stmtCtx); ok {
=======
if stmtCtx.UseCache && stmtAst.CachedPlan != nil && !ignorePlanCache { // for point query plan
if plan, names, ok, err := getCachedPointPlan(stmtAst, sessVars, stmtCtx); ok {
>>>>>>> 5327d07afc7 (planner: refactor plan-cache UseCache flag (#40256))
return plan, names, err
}
}

<<<<<<< HEAD
if stmtAst.UseCache && !ignorePlanCache { // for general plans
if plan, names, ok, err := getGeneralPlan(sctx, isGeneralPlanCache, cacheKey, bindSQL, is, stmt,
=======
if stmtCtx.UseCache && !ignorePlanCache { // for non-point plans
if plan, names, ok, err := getCachedPlan(sctx, isNonPrepared, cacheKey, bindSQL, is, stmt,
>>>>>>> 5327d07afc7 (planner: refactor plan-cache UseCache flag (#40256))
paramTypes); err != nil || ok {
return plan, names, err
}
Expand Down
17 changes: 17 additions & 0 deletions planner/core/plan_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ func TestPlanCacheDiagInfo(t *testing.T) {
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 skip plan-cache: some parameters may be overwritten"))
}

<<<<<<< HEAD
func TestIssue40224(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
Expand Down Expand Up @@ -344,4 +345,20 @@ func TestIssue40224(t *testing.T) {
{"IndexReader_6"},
{"└─IndexRangeScan_5"}, // range scan not full scan
})
=======
func TestUncacheableReason(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("prepare st from 'select * from t limit ?'")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 skip plan-cache: query has 'limit ?' is un-cacheable"))

tk.MustExec("set @a=1")
tk.MustQuery("execute st using @a").Check(testkit.Rows())
tk.MustExec("prepare st from 'select * from t limit ?'")
// show the corresponding un-cacheable reason at execute-stage as well
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 skip plan-cache: query has 'limit ?' is un-cacheable"))
>>>>>>> 5327d07afc7 (planner: refactor plan-cache UseCache flag (#40256))
}
26 changes: 25 additions & 1 deletion planner/core/plan_cache_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,19 @@ func GeneratePlanCacheStmtWithAST(ctx context.Context, sctx sessionctx.Context,
var (
normalizedSQL4PC, digest4PC string
selectStmtNode ast.StmtNode
cacheable bool
reason string
)
if !vars.EnablePreparedPlanCache {
prepared.UseCache = false
cacheable = false
reason = "plan cache is disabled"
} else {
<<<<<<< HEAD
cacheable, reason := CacheableWithCtx(sctx, stmt, ret.InfoSchema)
prepared.UseCache = cacheable
=======
cacheable, reason = CacheableWithCtx(sctx, paramStmt, ret.InfoSchema)
>>>>>>> 5327d07afc7 (planner: refactor plan-cache UseCache flag (#40256))
if !cacheable {
sctx.GetSessionVars().StmtCtx.AppendWarning(errors.Errorf("skip plan-cache: " + reason))
}
Expand Down Expand Up @@ -154,6 +161,8 @@ func GeneratePlanCacheStmtWithAST(ctx context.Context, sctx sessionctx.Context,
SnapshotTSEvaluator: ret.SnapshotTSEvaluator,
NormalizedSQL4PC: normalizedSQL4PC,
SQLDigest4PC: digest4PC,
StmtCacheable: cacheable,
UncacheableReason: reason,
}
if err = CheckPreparedPriv(sctx, preparedObj, ret.InfoSchema); err != nil {
return nil, nil, 0, err
Expand Down Expand Up @@ -414,11 +423,26 @@ func NewPlanCacheValue(plan Plan, names []*types.FieldName, srcMap map[*model.Ta

// PlanCacheStmt store prepared ast from PrepareExec and other related fields
type PlanCacheStmt struct {
<<<<<<< HEAD
PreparedAst *ast.Prepared
StmtDB string // which DB the statement will be processed over
VisitInfos []visitInfo
ColumnInfos interface{}
Executor interface{}
=======
PreparedAst *ast.Prepared
StmtDB string // which DB the statement will be processed over
VisitInfos []visitInfo
ColumnInfos interface{}
// Executor is only used for point get scene.
// Notice that we should only cache the PointGetExecutor that have a snapshot with MaxTS in it.
// If the current plan is not PointGet or does not use MaxTS optimization, this value should be nil here.
Executor interface{}

StmtCacheable bool // Whether this stmt is cacheable.
UncacheableReason string // Why this stmt is uncacheable.

>>>>>>> 5327d07afc7 (planner: refactor plan-cache UseCache flag (#40256))
NormalizedSQL string
NormalizedPlan string
SQLDigest *parser.Digest
Expand Down
2 changes: 1 addition & 1 deletion planner/core/prepare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func TestPointGetPreparedPlan4PlanCache(t *testing.T) {

pspk1Id, _, _, err := tk1.Session().PrepareStmt("select * from t where a = ?")
require.NoError(t, err)
tk1.Session().GetSessionVars().PreparedStmts[pspk1Id].(*core.PlanCacheStmt).PreparedAst.UseCache = false
tk1.Session().GetSessionVars().PreparedStmts[pspk1Id].(*core.PlanCacheStmt).StmtCacheable = false

ctx := context.Background()
// first time plan generated
Expand Down

0 comments on commit 202fe31

Please sign in to comment.