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: skip the optimizer for the execute statement #36612

Merged
merged 28 commits into from
Aug 8, 2022
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
36bf288
planner: skip the optimizer for the execute statement
Reminiscent Jul 27, 2022
547d9ca
refactor the code
Reminiscent Jul 27, 2022
6d1f37b
Merge branch 'master' of https://github.com/pingcap/tidb into refacto…
Reminiscent Jul 27, 2022
f97dba5
fix ut
Reminiscent Jul 28, 2022
a66a837
Merge branch 'master' of https://github.com/pingcap/tidb into refacto…
Reminiscent Jul 28, 2022
48d416d
fixut
Reminiscent Jul 28, 2022
3fbbfa2
Merge branch 'master' of https://github.com/pingcap/tidb into refacto…
Reminiscent Jul 28, 2022
3f8dcd0
Merge branch 'master' into refactor-PC-optimize
qw4990 Jul 29, 2022
13e754f
Merge branch 'master' of https://github.com/pingcap/tidb into refacto…
Reminiscent Jul 29, 2022
9751479
address comments
Reminiscent Aug 3, 2022
0942abb
Merge branch 'master' of https://github.com/pingcap/tidb into refacto…
Reminiscent Aug 3, 2022
4ed462b
Merge remote-tracking branch 'origin/refactor-PC-optimize' into refac…
Reminiscent Aug 3, 2022
58ef07f
Merge branch 'master' of https://github.com/pingcap/tidb into refacto…
Reminiscent Aug 4, 2022
a40f780
fix ut
Reminiscent Aug 4, 2022
41810fd
Merge branch 'master' into refactor-PC-optimize
Reminiscent Aug 4, 2022
ece4f7d
fix ut
Reminiscent Aug 5, 2022
2c554b6
Merge branch 'master' of https://github.com/pingcap/tidb into refacto…
Reminiscent Aug 5, 2022
91f5574
Merge remote-tracking branch 'origin/refactor-PC-optimize' into refac…
Reminiscent Aug 5, 2022
03a537d
address comments
Reminiscent Aug 5, 2022
ecdeb4a
address comments
Reminiscent Aug 5, 2022
08357a1
Merge branch 'master' of https://github.com/pingcap/tidb into refacto…
Reminiscent Aug 5, 2022
73dcf12
address comments
Reminiscent Aug 5, 2022
bfdf902
Merge branch 'master' into refactor-PC-optimize
qw4990 Aug 8, 2022
2292bf6
Merge branch 'master' into refactor-PC-optimize
qw4990 Aug 8, 2022
0788988
address comments
Reminiscent Aug 8, 2022
886d793
Merge branch 'master' of https://github.com/pingcap/tidb into refacto…
Reminiscent Aug 8, 2022
047e375
Merge remote-tracking branch 'origin/refactor-PC-optimize' into refac…
Reminiscent Aug 8, 2022
1e16078
Merge branch 'master' into refactor-PC-optimize
qw4990 Aug 8, 2022
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
18 changes: 15 additions & 3 deletions executor/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/sessiontxn"
"github.com/pingcap/tidb/sessiontxn/staleread"
"github.com/pingcap/tidb/types"
)

var (
Expand Down Expand Up @@ -77,9 +78,20 @@ func (c *Compiler) Compile(ctx context.Context, stmtNode ast.StmtNode) (*ExecStm
})

is := sessiontxn.GetTxnManager(c.Ctx).GetTxnInfoSchema()
finalPlan, names, err := planner.Optimize(ctx, c.Ctx, stmtNode, is)
if err != nil {
return nil, err
var (
finalPlan plannercore.Plan
names types.NameSlice
)
if execAST, ok := stmtNode.(*ast.ExecuteStmt); ok {
finalPlan, names, err = planner.OptimizeExecStmt(ctx, c.Ctx, execAST, is)
if err != nil {
return nil, err
}
} else {
finalPlan, names, err = planner.Optimize(ctx, c.Ctx, stmtNode, is)
if err != nil {
return nil, err
}
}

failpoint.Inject("assertStmtCtxIsStaleness", func(val failpoint.Value) {
Expand Down
2 changes: 1 addition & 1 deletion executor/prepared.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ func CompileExecutePreparedStmt(ctx context.Context, sctx sessionctx.Context,
defer func() {
sctx.GetSessionVars().DurationCompile = time.Since(startTime)
}()
execPlan, names, err := planner.Optimize(ctx, sctx, execStmt, is)
execPlan, names, err := planner.OptimizeExecStmt(ctx, sctx, execStmt, is)
if err != nil {
return nil, err
}
Expand Down
12 changes: 6 additions & 6 deletions planner/core/plan_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ func GetPlanFromSessionPlanCache(ctx context.Context, sctx sessionctx.Context, i
// 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 prepared.UseCache && prepared.CachedPlan != nil && !ignorePlanCache { // for point query plan
qw4990 marked this conversation as resolved.
Show resolved Hide resolved
if plan, names, ok, err := getPointQueryPlan(prepared, sessVars, stmtCtx); ok {
return plan, names, err
}
}

if prepared.UseCache {
bindSQL, ignorePlanCache = GetBindSQL4PlanCache(sctx, preparedStmt)
if sctx.GetSessionVars().IsIsolation(ast.ReadCommitted) || preparedStmt.ForUpdateRead {
Expand All @@ -74,12 +80,6 @@ func GetPlanFromSessionPlanCache(ctx context.Context, sctx sessionctx.Context, i

varsNum, txtVarTypes := parseParamTypes(sctx, txtProtoVars)

if prepared.UseCache && prepared.CachedPlan != nil && !ignorePlanCache { // for point query plan
if plan, names, ok, err := getPointQueryPlan(prepared, sessVars, stmtCtx); ok {
return plan, names, err
}
}

if prepared.UseCache && !ignorePlanCache { // for general plans
if plan, names, ok, err := getGeneralPlan(ctx, sctx, cacheKey, bindSQL, is, preparedStmt,
txtVarTypes); err != nil || ok {
Expand Down
67 changes: 51 additions & 16 deletions planner/optimize.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,31 +305,16 @@ func optimize(ctx context.Context, sctx sessionctx.Context, node ast.Node, is in
})

// build logical plan
sctx.GetSessionVars().PlanID = 0
sctx.GetSessionVars().PlanColumnID = 0
sctx.GetSessionVars().MapHashCode2UniqueID4ExtendedCol = nil
hintProcessor := &hint.BlockHintProcessor{Ctx: sctx}
node.Accept(hintProcessor)

failpoint.Inject("mockRandomPlanID", func() {
sctx.GetSessionVars().PlanID = rand.Intn(1000) // nolint:gosec
})

builder := planBuilderPool.Get().(*core.PlanBuilder)
defer planBuilderPool.Put(builder.ResetForReuse())

builder.Init(sctx, is, hintProcessor)

// reset fields about rewrite
sctx.GetSessionVars().RewritePhaseInfo.Reset()
beginRewrite := time.Now()
p, err := builder.Build(ctx, node)
p, err := buildLogicalPlan(ctx, sctx, node, builder)
if err != nil {
return nil, nil, 0, err
}
sctx.GetSessionVars().RewritePhaseInfo.DurationRewrite = time.Since(beginRewrite)

sctx.GetSessionVars().StmtCtx.Tables = builder.GetDBTableInfo()
activeRoles := sctx.GetSessionVars().ActiveRoles
// Check privilege. Maybe it's better to move this to the Preprocess, but
// we need the table information to check privilege, which is collected
Expand Down Expand Up @@ -371,6 +356,56 @@ func optimize(ctx context.Context, sctx sessionctx.Context, node ast.Node, is in
return finalPlan, names, cost, err
}

// OptimizeExecStmt to handle the "execute" statement
func OptimizeExecStmt(ctx context.Context, sctx sessionctx.Context,
qw4990 marked this conversation as resolved.
Show resolved Hide resolved
execAst *ast.ExecuteStmt, is infoschema.InfoSchema) (core.Plan, types.NameSlice, error) {
builder := planBuilderPool.Get().(*core.PlanBuilder)
defer planBuilderPool.Put(builder.ResetForReuse())
builder.Init(sctx, is, nil)

p, err := buildLogicalPlan(ctx, sctx, execAst, builder)
if err != nil {
return nil, nil, err
}
if execPlan, ok := p.(*core.Execute); ok {
// Because for write stmt, TiFlash has a different results when lock the data in point get plan. We ban the TiFlash
// engine in not read only stmt.
sessVars := sctx.GetSessionVars()
if _, isolationReadContainTiFlash := sessVars.IsolationReadEngines[kv.TiFlash]; isolationReadContainTiFlash && !IsReadOnly(execAst, sessVars) {
delete(sessVars.IsolationReadEngines, kv.TiFlash)
defer func() {
sessVars.IsolationReadEngines[kv.TiFlash] = struct{}{}
}()
}

err = execPlan.OptimizePreparedPlan(ctx, sctx, is)
return execPlan, execPlan.OutputNames(), err
}
err = errors.Errorf("invalid result plan type, should be Execute")
return nil, nil, err
}

func buildLogicalPlan(ctx context.Context, sctx sessionctx.Context, node ast.Node, builder *core.PlanBuilder) (core.Plan, error) {
sctx.GetSessionVars().PlanID = 0
sctx.GetSessionVars().PlanColumnID = 0
sctx.GetSessionVars().MapHashCode2UniqueID4ExtendedCol = nil

failpoint.Inject("mockRandomPlanID", func() {
sctx.GetSessionVars().PlanID = rand.Intn(1000) // nolint:gosec
})

// reset fields about rewrite
sctx.GetSessionVars().RewritePhaseInfo.Reset()
beginRewrite := time.Now()
p, err := builder.Build(ctx, node)
if err != nil {
return nil, err
}
sctx.GetSessionVars().RewritePhaseInfo.DurationRewrite = time.Since(beginRewrite)
sctx.GetSessionVars().StmtCtx.Tables = builder.GetDBTableInfo()
return p, nil
}

// ExtractSelectAndNormalizeDigest extract the select statement and normalize it.
func ExtractSelectAndNormalizeDigest(stmtNode ast.StmtNode, specifiledDB string) (ast.StmtNode, string, string, error) {
switch x := stmtNode.(type) {
Expand Down