Files
tidb/plan/plans.go

259 lines
6.1 KiB
Go

// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package plan
import (
"encoding/json"
"strings"
"github.com/juju/errors"
"github.com/pingcap/tidb/ast"
"github.com/pingcap/tidb/expression"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/util/auth"
"github.com/pingcap/tidb/util/types"
)
// ShowDDL is for showing DDL information.
type ShowDDL struct {
basePlan
}
// ShowDDLJobs is for showing DDL job list.
type ShowDDLJobs struct {
basePlan
}
// CheckTable is used for checking table data, built from the 'admin check table' statement.
type CheckTable struct {
basePlan
Tables []*ast.TableName
}
// SelectLock represents a select lock plan.
type SelectLock struct {
*basePlan
baseLogicalPlan
basePhysicalPlan
Lock ast.SelectLockType
}
// Prepare represents prepare plan.
type Prepare struct {
basePlan
Name string
SQLText string
}
// Execute represents prepare plan.
type Execute struct {
basePlan
Name string
UsingVars []expression.Expression
ExecID uint32
}
// Deallocate represents deallocate plan.
type Deallocate struct {
basePlan
Name string
}
// Show represents a show plan.
type Show struct {
*basePlan
baseLogicalPlan
basePhysicalPlan
Tp ast.ShowStmtType // Databases/Tables/Columns/....
DBName string
Table *ast.TableName // Used for showing columns.
Column *ast.ColumnName // Used for `desc table column`.
Flag int // Some flag parsed from sql, such as FULL.
Full bool
User *auth.UserIdentity // Used for show grants.
// Used by show variables
GlobalScope bool
}
// Set represents a plan for set stmt.
type Set struct {
basePlan
VarAssigns []*expression.VarAssignment
}
// Simple represents a simple statement plan which doesn't need any optimization.
type Simple struct {
basePlan
Statement ast.StmtNode
}
// InsertGeneratedColumns is for completing generated columns in Insert.
// We resolve generation expressions in plan, and eval those in executor.
type InsertGeneratedColumns struct {
Columns []*ast.ColumnName
Exprs []expression.Expression
OnDuplicates []*expression.Assignment
}
// Insert represents an insert plan.
type Insert struct {
*basePlan
baseLogicalPlan
basePhysicalPlan
Table table.Table
tableSchema *expression.Schema
Columns []*ast.ColumnName
Lists [][]expression.Expression
Setlist []*expression.Assignment
OnDuplicate []*expression.Assignment
IsReplace bool
Priority mysql.PriorityEnum
IgnoreErr bool
GenCols InsertGeneratedColumns
}
// AnalyzeColumnsTask is used for analyze columns.
type AnalyzeColumnsTask struct {
TableInfo *model.TableInfo
PKInfo *model.ColumnInfo
ColsInfo []*model.ColumnInfo
}
// AnalyzeIndexTask is used for analyze index.
type AnalyzeIndexTask struct {
TableInfo *model.TableInfo
IndexInfo *model.IndexInfo
}
// Analyze represents an analyze plan
type Analyze struct {
basePlan
ColTasks []AnalyzeColumnsTask
IdxTasks []AnalyzeIndexTask
}
// LoadData represents a loaddata plan.
type LoadData struct {
basePlan
IsLocal bool
Path string
Table *ast.TableName
Columns []*ast.ColumnName
FieldsInfo *ast.FieldsClause
LinesInfo *ast.LinesClause
GenCols InsertGeneratedColumns
}
// DDL represents a DDL statement plan.
type DDL struct {
basePlan
Statement ast.DDLNode
}
// Explain represents a explain plan.
type Explain struct {
basePlan
StmtPlan Plan
Rows [][]types.Datum
explainedPlans map[int]bool
}
func (e *Explain) prepareExplainInfo(p Plan, parent Plan) error {
for _, child := range p.Children() {
err := e.prepareExplainInfo(child, p)
if err != nil {
return errors.Trace(err)
}
}
explain, err := json.MarshalIndent(p, "", " ")
if err != nil {
return errors.Trace(err)
}
parentStr := ""
if parent != nil {
parentStr = parent.ExplainID()
}
row := types.MakeDatums(p.ExplainID(), string(explain), parentStr)
e.Rows = append(e.Rows, row)
return nil
}
// prepareExplainInfo4DAGTask generates the following information for every plan:
// ["id", "parents", "task", "operator info"].
func (e *Explain) prepareExplainInfo4DAGTask(p PhysicalPlan, taskType string) {
parents := p.Parents()
parentIDs := make([]string, 0, len(parents))
for _, parent := range parents {
parentIDs = append(parentIDs, parent.ExplainID())
}
childrenIDs := make([]string, 0, len(p.Children()))
for _, ch := range p.Children() {
childrenIDs = append(childrenIDs, ch.ExplainID())
}
parentInfo := strings.Join(parentIDs, ",")
childrenInfo := strings.Join(childrenIDs, ",")
operatorInfo := p.ExplainInfo()
count := p.statsProfile().count
row := types.MakeDatums(p.ExplainID(), parentInfo, childrenInfo, taskType, operatorInfo, count)
e.Rows = append(e.Rows, row)
}
// prepareCopTaskInfo generates explain information for cop-tasks.
// Only PhysicalTableReader, PhysicalIndexReader and PhysicalIndexLookUpReader have cop-tasks currently.
func (e *Explain) prepareCopTaskInfo(plans []PhysicalPlan) {
for _, p := range plans {
e.prepareExplainInfo4DAGTask(p, "cop")
}
}
// prepareRootTaskInfo generates explain information for root-tasks.
func (e *Explain) prepareRootTaskInfo(p PhysicalPlan) {
e.explainedPlans[p.ID()] = true
for _, child := range p.Children() {
if e.explainedPlans[child.ID()] {
continue
}
e.prepareRootTaskInfo(child.(PhysicalPlan))
}
switch copPlan := p.(type) {
case *PhysicalTableReader:
e.prepareCopTaskInfo(copPlan.TablePlans)
case *PhysicalIndexReader:
e.prepareCopTaskInfo(copPlan.IndexPlans)
case *PhysicalIndexLookUpReader:
e.prepareCopTaskInfo(copPlan.IndexPlans)
e.prepareCopTaskInfo(copPlan.TablePlans)
}
e.prepareExplainInfo4DAGTask(p, "root")
}