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
plan, executor: no longer treat dml as logical/physical plan. #5230
Changes from 4 commits
14bae9e
e3805f9
b09a287
8d671bc
3a3c9db
b472581
47248a2
f450096
0dd8cc0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -313,9 +313,7 @@ func (b *executorBuilder) buildInsert(v *plan.Insert) Executor { | |
GenExprs: v.GenCols.Exprs, | ||
needFillDefaultValues: v.NeedFillDefaultValue, | ||
} | ||
if len(v.Children()) > 0 { | ||
ivs.SelectExec = b.build(v.Children()[0]) | ||
} | ||
ivs.SelectExec = b.build(v.SelectPlan) | ||
ivs.Table = v.Table | ||
if v.IsReplace { | ||
return b.buildReplace(ivs) | ||
|
@@ -778,12 +776,12 @@ func (b *executorBuilder) buildUnion(v *plan.Union) Executor { | |
|
||
func (b *executorBuilder) buildUpdate(v *plan.Update) Executor { | ||
tblID2table := make(map[int64]table.Table) | ||
for id := range v.Schema().TblID2Handle { | ||
for id := range v.SelectPlan.Schema().TblID2Handle { | ||
tblID2table[id], _ = b.is.TableByID(id) | ||
} | ||
return &UpdateExec{ | ||
baseExecutor: newBaseExecutor(nil, b.ctx), | ||
SelectExec: b.build(v.Children()[0]), | ||
SelectExec: b.build(v.SelectPlan), | ||
OrderedList: v.OrderedList, | ||
tblID2table: tblID2table, | ||
IgnoreErr: v.IgnoreErr, | ||
|
@@ -792,12 +790,12 @@ func (b *executorBuilder) buildUpdate(v *plan.Update) Executor { | |
|
||
func (b *executorBuilder) buildDelete(v *plan.Delete) Executor { | ||
tblID2table := make(map[int64]table.Table) | ||
for id := range v.Schema().TblID2Handle { | ||
for id := range v.SelectPlan.Schema().TblID2Handle { | ||
tblID2table[id], _ = b.is.TableByID(id) | ||
} | ||
return &DeleteExec{ | ||
baseExecutor: newBaseExecutor(nil, b.ctx), | ||
SelectExec: b.build(v.Children()[0]), | ||
SelectExec: b.build(v.SelectPlan), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
Tables: v.Tables, | ||
IsMultiTable: v.IsMultiTable, | ||
tblID2Table: tblID2table, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1781,7 +1781,7 @@ func (b *planBuilder) buildSemiJoin(outerPlan, innerPlan LogicalPlan, onConditio | |
return joinPlan | ||
} | ||
|
||
func (b *planBuilder) buildUpdate(update *ast.UpdateStmt) LogicalPlan { | ||
func (b *planBuilder) buildUpdate(update *ast.UpdateStmt) Plan { | ||
b.inUpdateStmt = true | ||
sel := &ast.SelectStmt{Fields: &ast.FieldList{}, From: update.TableRefs, Where: update.Where, OrderBy: update.Order, Limit: update.Limit} | ||
p := b.buildResultSetNode(sel.From.TableRefs) | ||
|
@@ -1827,8 +1827,8 @@ func (b *planBuilder) buildUpdate(update *ast.UpdateStmt) LogicalPlan { | |
OrderedList: orderedList, | ||
IgnoreErr: update.IgnoreErr, | ||
}.init(b.ctx) | ||
setParentAndChildren(updt, p) | ||
updt.SetSchema(p.Schema()) | ||
updt.SelectPlan, b.err = doOptimize(b.optFlag, p, b.ctx) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. check b.err There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If b.err is not nil, we can also return. It's no need to check this. |
||
return updt | ||
} | ||
|
||
|
@@ -1943,7 +1943,7 @@ func extractTableAsNameForUpdate(p Plan, asNames map[*model.TableInfo][]*model.C | |
} | ||
} | ||
|
||
func (b *planBuilder) buildDelete(delete *ast.DeleteStmt) LogicalPlan { | ||
func (b *planBuilder) buildDelete(delete *ast.DeleteStmt) Plan { | ||
sel := &ast.SelectStmt{Fields: &ast.FieldList{}, From: delete.TableRefs, Where: delete.Where, OrderBy: delete.Order, Limit: delete.Limit} | ||
p := b.buildResultSetNode(sel.From.TableRefs) | ||
if b.err != nil { | ||
|
@@ -1978,7 +1978,10 @@ func (b *planBuilder) buildDelete(delete *ast.DeleteStmt) LogicalPlan { | |
Tables: tables, | ||
IsMultiTable: delete.IsMultiTable, | ||
}.init(b.ctx) | ||
setParentAndChildren(del, p) | ||
del.SelectPlan, b.err = doOptimize(b.optFlag, p, b.ctx) | ||
if b.err != nil { | ||
return nil | ||
} | ||
del.SetSchema(expression.NewSchema()) | ||
|
||
var tableList []*ast.TableName | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -612,19 +612,19 @@ func (s *testPlanSuite) TestPlanBuilder(c *C) { | |
}, | ||
{ | ||
sql: "update t set t.a = t.a * 1.5 where t.a >= 1000 order by t.a desc limit 10", | ||
plan: "DataScan(t)->Sel([ge(test.t.a, 1000)])->Sort->Limit->*plan.Update", | ||
plan: "TableReader(Table(t)->Limit)->Limit->Update", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why DataScan is replaced with TableReader? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We build update's |
||
}, | ||
{ | ||
sql: "delete from t where t.a >= 1000 order by t.a desc limit 10", | ||
plan: "DataScan(t)->Sel([ge(test.t.a, 1000)])->Sort->Limit->*plan.Delete", | ||
plan: "TableReader(Table(t)->Limit)->Limit->Delete", | ||
}, | ||
{ | ||
sql: "explain select * from t union all select * from t limit 1, 1", | ||
plan: "*plan.Explain", | ||
}, | ||
{ | ||
sql: "insert into t select * from t", | ||
plan: "DataScan(t)->Projection->*plan.Insert", | ||
plan: "TableReader(Table(t))->Insert", | ||
}, | ||
{ | ||
sql: "show columns from t where `Key` = 'pri' like 't*'", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,6 +52,9 @@ type Plan interface { | |
// findColumn finds the column in basePlan's schema. | ||
// If the column is not in the schema, returns error. | ||
findColumn(*ast.ColumnName) (*expression.Column, int, error) | ||
|
||
// ResolveIndices resolves the indices for columns. After doing this, the columns can evaluate the rows by their indices. | ||
ResolveIndices() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why move this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Insert/Delete/Update also needs resolveIndices |
||
} | ||
|
||
// taskType is the type of execution task. | ||
|
@@ -197,9 +200,6 @@ type PhysicalPlan interface { | |
|
||
// statsProfile will return the stats for this plan. | ||
statsProfile() *statsProfile | ||
|
||
// ResolveIndices resolves the indices for columns. After doing this, the columns can evaluate the rows by their indices. | ||
ResolveIndices() | ||
} | ||
|
||
type baseLogicalPlan struct { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
after building, we should check
b.err
:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if b.err is not nil, it's ok to return any executor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to discover error as soon as possible so that we can avoid useless executor building.