From 4023bb88b3e286e7c5c64c155365494e25814cc0 Mon Sep 17 00:00:00 2001 From: Lynn Date: Tue, 4 Jul 2017 00:13:08 +0800 Subject: [PATCH] plan: Clean up (#3606) --- plan/logical_plan_builder.go | 26 ++++++++++++-------------- plan/new_physical_plan_builder.go | 28 ++++++++++++++-------------- plan/optimizer.go | 2 +- plan/planbuilder.go | 6 +++--- table/tables/tables.go | 9 ++++++++- 5 files changed, 38 insertions(+), 33 deletions(-) diff --git a/plan/logical_plan_builder.go b/plan/logical_plan_builder.go index d609613fc4add..e5571fd315af8 100644 --- a/plan/logical_plan_builder.go +++ b/plan/logical_plan_builder.go @@ -25,6 +25,7 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/statistics" + "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/util/types" ) @@ -952,8 +953,8 @@ func (b *planBuilder) pushTableHints(hints []*ast.TableOptimizerHint) bool { } if len(sortMergeTables) != 0 || len(INLJTables) != 0 { b.tableHintInfo = append(b.tableHintInfo, tableHintInfo{ - sortMergeJoinTables: sortMergeTables, - INLJTables: INLJTables, + sortMergeJoinTables: sortMergeTables, + indexNestedLoopJoinTables: INLJTables, }) return true } @@ -1107,23 +1108,20 @@ func (b *planBuilder) buildDataSource(tn *ast.TableName) LogicalPlan { tableInfo: tableInfo, statisticTable: statisticTable, DBName: schemaName, + Columns: make([]*model.ColumnInfo, 0, len(tableInfo.Columns)), }.init(b.allocator, b.ctx) b.visitInfo = appendVisitInfo(b.visitInfo, mysql.SelectPriv, schemaName.L, tableInfo.Name.L, "") - // Equal condition contains a column from previous joined table. schema := expression.NewSchema(make([]*expression.Column, 0, len(tableInfo.Columns))...) - for i, col := range tableInfo.Columns { - if b.inUpdateStmt { - switch col.State { - case model.StatePublic, model.StateWriteOnly, model.StateWriteReorganization: - default: - continue - } - } else if col.State != model.StatePublic { - continue - } - p.Columns = append(p.Columns, col) + var columns []*table.Column + if b.inUpdateStmt { + columns = tbl.WritableCols() + } else { + columns = tbl.Cols() + } + for i, col := range columns { + p.Columns = append(p.Columns, col.ColumnInfo) schema.Append(&expression.Column{ FromID: p.id, ColName: col.Name, diff --git a/plan/new_physical_plan_builder.go b/plan/new_physical_plan_builder.go index 5209bd5462335..ae1c98f3b338f 100644 --- a/plan/new_physical_plan_builder.go +++ b/plan/new_physical_plan_builder.go @@ -109,17 +109,15 @@ func (p *LogicalJoin) convertToIndexJoin(prop *requiredProp, outerIdx int) (task outerChild := p.children[outerIdx].(LogicalPlan) innerChild := p.children[1-outerIdx].(LogicalPlan) var ( - outerTask task useTableScan bool usedIndexInfo *model.IndexInfo rightConds expression.CNFExprs leftConds expression.CNFExprs innerTask task - err error innerJoinKeys []*expression.Column outerJoinKeys []*expression.Column ) - outerTask, err = outerChild.convert2NewPhysicalPlan(&requiredProp{taskTp: rootTaskType}) + outerTask, err := outerChild.convert2NewPhysicalPlan(&requiredProp{taskTp: rootTaskType}) if err != nil { return nil, errors.Trace(err) } @@ -152,18 +150,20 @@ func (p *LogicalJoin) convertToIndexJoin(prop *requiredProp, outerIdx int) (task break } for _, indexInfo := range indices { - if matchedOffsets := joinKeysMatchIndex(innerJoinKeys, indexInfo); matchedOffsets != nil { - usedIndexInfo = indexInfo - newOuterJoinKeys := make([]*expression.Column, len(outerJoinKeys)) - newInnerJoinKeys := make([]*expression.Column, len(innerJoinKeys)) - for i, offset := range matchedOffsets { - newOuterJoinKeys[i] = outerJoinKeys[offset] - newInnerJoinKeys[i] = innerJoinKeys[offset] - } - outerJoinKeys = newOuterJoinKeys - innerJoinKeys = newInnerJoinKeys - break + matchedOffsets := joinKeysMatchIndex(innerJoinKeys, indexInfo) + if matchedOffsets == nil { + continue } + usedIndexInfo = indexInfo + newOuterJoinKeys := make([]*expression.Column, len(outerJoinKeys)) + newInnerJoinKeys := make([]*expression.Column, len(innerJoinKeys)) + for i, offset := range matchedOffsets { + newOuterJoinKeys[i] = outerJoinKeys[offset] + newInnerJoinKeys[i] = innerJoinKeys[offset] + } + outerJoinKeys = newOuterJoinKeys + innerJoinKeys = newInnerJoinKeys + break } if usedIndexInfo != nil { innerTask, err = x.convertToIndexScan(&requiredProp{taskTp: rootTaskType}, usedIndexInfo) diff --git a/plan/optimizer.go b/plan/optimizer.go index aea6954c838c3..7332deea1f5f2 100644 --- a/plan/optimizer.go +++ b/plan/optimizer.go @@ -122,7 +122,6 @@ func doOptimize(flag uint64, logic LogicalPlan, ctx context.Context, allocator * if UseDAGPlanBuilder(ctx) { return dagPhysicalOptimize(logic) } - logic.ResolveIndices() return physicalOptimize(flag, logic, allocator) } @@ -155,6 +154,7 @@ func dagPhysicalOptimize(logic LogicalPlan) (PhysicalPlan, error) { } func physicalOptimize(flag uint64, logic LogicalPlan, allocator *idAllocator) (PhysicalPlan, error) { + logic.ResolveIndices() info, err := logic.convert2PhysicalPlan(&requiredProperty{}) if err != nil { return nil, errors.Trace(err) diff --git a/plan/planbuilder.go b/plan/planbuilder.go index bcac7916be6e9..3c7b1193c5ac0 100644 --- a/plan/planbuilder.go +++ b/plan/planbuilder.go @@ -71,8 +71,8 @@ type visitInfo struct { } type tableHintInfo struct { - INLJTables []model.CIStr - sortMergeJoinTables []model.CIStr + indexNestedLoopJoinTables []model.CIStr + sortMergeJoinTables []model.CIStr } func (info *tableHintInfo) ifPreferMergeJoin(tableNames ...*model.CIStr) bool { @@ -101,7 +101,7 @@ func (info *tableHintInfo) ifPreferINLJ(tableNames ...*model.CIStr) bool { if tableName == nil { continue } - for _, curEntry := range info.INLJTables { + for _, curEntry := range info.indexNestedLoopJoinTables { if curEntry.L == tableName.L { return true } diff --git a/table/tables/tables.go b/table/tables/tables.go index cea22320b3402..061a981d6183c 100644 --- a/table/tables/tables.go +++ b/table/tables/tables.go @@ -56,7 +56,14 @@ type Table struct { // MockTableFromMeta only serves for test. func MockTableFromMeta(tableInfo *model.TableInfo) table.Table { - return &Table{ID: 0, meta: tableInfo} + columns := make([]*table.Column, 0, len(tableInfo.Columns)) + for _, colInfo := range tableInfo.Columns { + col := table.ToColumn(colInfo) + columns = append(columns, col) + } + t := newTable(tableInfo.ID, columns, nil) + t.meta = tableInfo + return t } // TableFromMeta creates a Table instance from model.TableInfo.