-
Notifications
You must be signed in to change notification settings - Fork 5.8k
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
support hash join in new plan #1234
Changes from 1 commit
c1a557f
b5355a9
b7338aa
ac5757b
4915b5b
7103381
68b6da2
ebf166d
b526229
9c210da
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 |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// Copyright 2015 PingCAP, Inc. | ||
// Copyright 2016 PingCAP, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
|
@@ -14,6 +14,7 @@ | |
package plan | ||
|
||
import ( | ||
"github.com/juju/errors" | ||
"github.com/pingcap/tidb/ast" | ||
) | ||
|
||
|
@@ -29,7 +30,7 @@ const ( | |
LeftOuterJoin | ||
// RightOuterJoin means right join | ||
RightOuterJoin | ||
// todo: support semi join | ||
// TODO: support semi join. | ||
) | ||
|
||
// Join is the logical join plan | ||
|
@@ -43,3 +44,46 @@ type Join struct { | |
RightConditions []ast.ExprNode | ||
OtherConditions []ast.ExprNode | ||
} | ||
|
||
// AddChild for parent | ||
func AddChild(parent Plan, child Plan) { | ||
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. Will this be used by other package? So we make it private? |
||
if child == nil || parent == nil { | ||
return | ||
} | ||
child.AddParent(parent) | ||
parent.AddChild(child) | ||
} | ||
|
||
// InsertPlan means inserting plan between two plans | ||
func InsertPlan(child Plan, parent Plan, insert Plan) error { | ||
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. Change the parameter order to |
||
err := child.ReplaceParent(parent, insert) | ||
if err != nil { | ||
return errors.Trace(err) | ||
} | ||
err = parent.ReplaceChild(child, insert) | ||
if err != nil { | ||
return errors.Trace(err) | ||
} | ||
insert.AddChild(child) | ||
insert.AddParent(parent) | ||
return err | ||
} | ||
|
||
// RemovePlan means removing a plan | ||
func RemovePlan(p Plan) error { | ||
parents := p.GetParents() | ||
children := p.GetChildren() | ||
if len(parents) != 1 || len(children) != 1 { | ||
return SystemInternalErrorType.Gen("can't remove this plan") | ||
} | ||
parent, child := parents[0], children[0] | ||
err := parent.ReplaceChild(p, child) | ||
if err != nil { | ||
return errors.Trace(err) | ||
} | ||
err = child.ReplaceParent(p, parent) | ||
if err != nil { | ||
return errors.Trace(err) | ||
} | ||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// Copyright 2015 PingCAP, Inc. | ||
// Copyright 2016 PingCAP, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
|
@@ -14,8 +14,6 @@ | |
package plan | ||
|
||
import ( | ||
"fmt" | ||
"github.com/ngaut/log" | ||
"github.com/pingcap/tidb/ast" | ||
"github.com/pingcap/tidb/model" | ||
"github.com/pingcap/tidb/mysql" | ||
|
@@ -36,7 +34,7 @@ func (b *planBuilder) buildNewSinglePathPlan(node ast.ResultSetNode) Plan { | |
case *ast.UnionStmt: | ||
return b.buildUnion(v) | ||
case *ast.TableName: | ||
//todo: select physical algorithm during cbo phase. | ||
//TODO: select physical algorithm during cbo phase. | ||
return b.buildNewTableScanPlan(v) | ||
default: | ||
b.err = ErrUnsupportedType.Gen("unsupported table source type %T", v) | ||
|
@@ -57,30 +55,20 @@ func fromFields(col *ast.ColumnNameExpr, fields []*ast.ResultField) bool { | |
return false | ||
} | ||
|
||
func extractColumns(expr ast.ExprNode) (cols []*ast.ColumnNameExpr, ok bool) { | ||
ok = true | ||
type columnsExtractor struct { | ||
result []*ast.ColumnNameExpr | ||
} | ||
|
||
func (ce *columnsExtractor) Enter(expr ast.Node) (ret ast.Node, ok bool) { | ||
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.
|
||
switch v := expr.(type) { | ||
case *ast.FuncCallExpr: | ||
for _, arg := range v.Args { | ||
argCols, ok := extractColumns(arg) | ||
if !ok { | ||
return nil, false | ||
} | ||
cols = append(cols, argCols...) | ||
} | ||
case *ast.ColumnNameExpr: | ||
cols = append(cols, v) | ||
case *ast.FuncCastExpr: | ||
argCols, ok := extractColumns(v.Expr) | ||
if !ok { | ||
return nil, false | ||
} | ||
cols = append(cols, argCols...) | ||
case *ast.ValueExpr: | ||
default: | ||
return nil, false | ||
ce.result = append(ce.result, v) | ||
} | ||
return cols, ok | ||
return expr, false | ||
} | ||
|
||
func (ce *columnsExtractor) Leave(expr ast.Node) (ret ast.Node, ok bool) { | ||
return expr, false | ||
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.
|
||
} | ||
|
||
func extractOnCondition(conditions []ast.ExprNode, left Plan, right Plan) (eqCond []ast.ExprNode, leftCond []ast.ExprNode, rightCond []ast.ExprNode, otherCond []ast.ExprNode) { | ||
|
@@ -99,24 +87,21 @@ func extractOnCondition(conditions []ast.ExprNode, left Plan, right Plan) (eqCon | |
} | ||
} | ||
} | ||
columns, ok := extractColumns(expr) | ||
if ok { | ||
allFromLeft, allFromRight := true, true | ||
for _, col := range columns { | ||
if fromFields(col, left.Fields()) { | ||
allFromRight = false | ||
} else { | ||
allFromLeft = false | ||
} | ||
} | ||
if allFromLeft { | ||
leftCond = append(leftCond, expr) | ||
} | ||
if allFromRight { | ||
rightCond = append(rightCond, expr) | ||
} else if !allFromLeft { | ||
otherCond = append(otherCond, expr) | ||
ce := &columnsExtractor{} | ||
expr.Accept(ce) | ||
columns := ce.result | ||
allFromLeft, allFromRight := true, true | ||
for _, col := range columns { | ||
if fromFields(col, left.Fields()) { | ||
allFromRight = false | ||
} else { | ||
allFromLeft = false | ||
} | ||
} | ||
if allFromRight { | ||
rightCond = append(rightCond, expr) | ||
} else if allFromLeft { | ||
leftCond = append(leftCond, expr) | ||
} else { | ||
otherCond = append(otherCond, expr) | ||
} | ||
|
@@ -140,20 +125,16 @@ func (b *planBuilder) buildNewJoin(join *ast.Join) Plan { | |
} else { | ||
joinPlan.JoinType = InnerJoin | ||
} | ||
joinPlan.AddChild(leftPlan) | ||
joinPlan.AddChild(rightPlan) | ||
leftPlan.AddParent(joinPlan) | ||
rightPlan.AddParent(joinPlan) | ||
AddChild(joinPlan, leftPlan) | ||
AddChild(joinPlan, rightPlan) | ||
joinPlan.SetFields(append(leftPlan.Fields(), rightPlan.Fields()...)) | ||
log.Infof(fmt.Sprintf("build join plan %v", joinPlan.GetChildren())) | ||
return joinPlan | ||
} | ||
|
||
func (b *planBuilder) buildFilter(p Plan, where ast.ExprNode) Plan { | ||
conditions := splitWhere(where) | ||
filter := &Filter{Conditions: conditions} | ||
filter.AddChild(p) | ||
p.AddParent(filter) | ||
AddChild(filter, p) | ||
filter.SetFields(p.Fields()) | ||
return filter | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -541,14 +541,12 @@ func (b *planBuilder) buildPseudoSelectPlan(p Plan, sel *ast.SelectStmt) Plan { | |
x.NoLimit = true | ||
} | ||
np := &Sort{ByItems: sel.OrderBy.Items} | ||
np.AddChild(p) | ||
p.AddParent(np) | ||
AddChild(np, p) | ||
p = np | ||
} | ||
if sel.Limit != nil { | ||
np := &Limit{Offset: sel.Limit.Offset, Count: sel.Limit.Count} | ||
np.AddChild(p) | ||
p.AddParent(np) | ||
AddChild(np, p) | ||
np.SetLimit(0) | ||
p = np | ||
} else { | ||
|
@@ -564,20 +562,14 @@ func (b *planBuilder) buildSelectLock(src Plan, lock ast.SelectLockType) *Select | |
selectLock := &SelectLock{ | ||
Lock: lock, | ||
} | ||
if src != nil { | ||
selectLock.AddChild(src) | ||
src.AddParent(selectLock) | ||
} | ||
AddChild(selectLock, src) | ||
selectLock.SetFields(src.Fields()) | ||
return selectLock | ||
} | ||
|
||
func (b *planBuilder) buildSelectFields(src Plan, fields []*ast.ResultField) Plan { | ||
selectFields := &SelectFields{} | ||
if src != nil { | ||
selectFields.AddChild(src) | ||
src.AddParent(selectFields) | ||
} | ||
AddChild(selectFields, src) | ||
selectFields.SetFields(fields) | ||
return selectFields | ||
} | ||
|
@@ -587,10 +579,7 @@ func (b *planBuilder) buildAggregate(src Plan, aggFuncs []*ast.AggregateFuncExpr | |
aggPlan := &Aggregate{ | ||
AggFuncs: aggFuncs, | ||
} | ||
if src != nil { | ||
aggPlan.AddChild(src) | ||
src.AddParent(aggPlan) | ||
} | ||
AddChild(aggPlan, src) | ||
if src != nil { | ||
aggPlan.SetFields(src.Fields()) | ||
} | ||
|
@@ -604,7 +593,7 @@ func (b *planBuilder) buildHaving(src Plan, having *ast.HavingClause) Plan { | |
p := &Having{ | ||
Conditions: splitWhere(having.Expr), | ||
} | ||
p.AddChild(src) | ||
AddChild(p, src) | ||
src.AddParent(p) | ||
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. This line should be removed. |
||
p.SetFields(src.Fields()) | ||
return p | ||
|
@@ -614,8 +603,7 @@ func (b *planBuilder) buildSort(src Plan, byItems []*ast.ByItem) Plan { | |
sort := &Sort{ | ||
ByItems: byItems, | ||
} | ||
sort.AddChild(src) | ||
src.AddParent(sort) | ||
AddChild(sort, src) | ||
sort.SetFields(src.Fields()) | ||
return sort | ||
} | ||
|
@@ -629,8 +617,7 @@ func (b *planBuilder) buildLimit(src Plan, limit *ast.Limit) Plan { | |
s.ExecLimit = li | ||
return s | ||
} | ||
li.AddChild(src) | ||
src.AddParent(li) | ||
AddChild(li, src) | ||
li.SetFields(src.Fields()) | ||
return li | ||
} | ||
|
@@ -910,7 +897,7 @@ func (b *planBuilder) buildUnion(union *ast.UnionStmt) Plan { | |
|
||
func (b *planBuilder) buildDistinct(src Plan) Plan { | ||
d := &Distinct{} | ||
d.AddChild(src) | ||
AddChild(d, src) | ||
src.AddParent(d) | ||
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. remove this line. |
||
d.SetFields(src.Fields()) | ||
return d | ||
|
@@ -1054,8 +1041,7 @@ func (b *planBuilder) buildShow(show *ast.ShowStmt) Plan { | |
} | ||
if len(conditions) != 0 { | ||
filter := &Filter{Conditions: conditions} | ||
filter.AddChild(p) | ||
p.AddParent(filter) | ||
AddChild(filter, p) | ||
p = filter | ||
} | ||
return p | ||
|
@@ -1077,10 +1063,7 @@ func (b *planBuilder) buildInsert(insert *ast.InsertStmt) Plan { | |
} | ||
if insert.Select != nil { | ||
insertPlan.SelectPlan = b.build(insert.Select) | ||
if insertPlan.SelectPlan != nil { | ||
insertPlan.AddChild(insertPlan.SelectPlan) | ||
insertPlan.SelectPlan.AddParent(insertPlan) | ||
} | ||
AddChild(insertPlan, insertPlan.SelectPlan) | ||
if b.err != nil { | ||
return nil | ||
} | ||
|
@@ -1101,10 +1084,7 @@ func (b *planBuilder) buildExplain(explain *ast.ExplainStmt) Plan { | |
return nil | ||
} | ||
p := &Explain{StmtPlan: targetPlan} | ||
if targetPlan != nil { | ||
p.AddChild(targetPlan) | ||
targetPlan.AddParent(p) | ||
} | ||
AddChild(p, targetPlan) | ||
p.SetFields(buildExplainFields()) | ||
return p | ||
} | ||
|
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.
2016 -> 2015 ?