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

support hash join in new plan #1234

Merged
merged 10 commits into from
May 19, 2016
Merged
4 changes: 2 additions & 2 deletions executor/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func composeCondition(conditions []ast.ExprNode) ast.ExprNode {
}
}

//todo: select join algorithm during cbo phase
//TODO: select join algorithm during cbo phase.
func (b *executorBuilder) buildJoin(v *plan.Join) Executor {
e := &HashJoinExec{
otherFilter: composeCondition(v.OtherConditions),
Expand Down Expand Up @@ -163,7 +163,7 @@ func (b *executorBuilder) buildJoin(v *plan.Join) Executor {
e.smallHashKey = leftHashKey
e.bigHashKey = rightHashKey
case plan.InnerJoin:
//todo: assume right table is the small one before cbo is realized.
//TODO: assume right table is the small one before cbo is realized.
e.outter = false
e.leftSmall = false
big, small = 0, 1
Expand Down
2 changes: 1 addition & 1 deletion executor/executor_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2015 PingCAP, Inc.
// Copyright 2016 PingCAP, Inc.
Copy link
Contributor

@zimulala zimulala May 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2016 -> 2015 ?

//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down
9 changes: 6 additions & 3 deletions executor/new_executor.go
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.
Expand Down Expand Up @@ -118,7 +118,6 @@ func (e *HashJoinExec) Next() (*Row, error) {
e.bigExec.Close()
return nil, nil
}
hashcode, err := e.getHashKey(e.bigHashKey)
var matchedRows []*Row
bigMatched := true
if e.bigFilter != nil {
Expand All @@ -128,10 +127,14 @@ func (e *HashJoinExec) Next() (*Row, error) {
return nil, errors.Trace(err)
}
if bigMatched {
hashcode, err := e.getHashKey(e.bigHashKey)
if err != nil {
return nil, errors.Trace(err)
}
// match eq condition
if rows, ok := e.hashTable[hashcode]; ok {
for _, smallRow := range rows {
//todo: remove result fields in order to reduce memory copy cost
//TODO: remove result fields in order to reduce memory copy cost.
startKey := 0
if !e.leftSmall {
startKey = len(bigRow.Data)
Expand Down
48 changes: 46 additions & 2 deletions optimizer/plan/new_plans.go
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.
Expand All @@ -14,6 +14,7 @@
package plan

import (
"github.com/juju/errors"
"github.com/pingcap/tidb/ast"
)

Expand All @@ -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
Expand All @@ -43,3 +44,46 @@ type Join struct {
RightConditions []ast.ExprNode
OtherConditions []ast.ExprNode
}

// AddChild for parent
func AddChild(parent Plan, child Plan) {
Copy link
Member

Choose a reason for hiding this comment

The 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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the parameter order to parent, child, insert would be better, which is consistent with the AddChild method above.

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
}
79 changes: 30 additions & 49 deletions optimizer/plan/newplanbuilder.go
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.
Expand All @@ -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"
Expand All @@ -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)
Expand All @@ -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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok -> skipChildren

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return expr, true

}

func extractOnCondition(conditions []ast.ExprNode, left Plan, right Plan) (eqCond []ast.ExprNode, leftCond []ast.ExprNode, rightCond []ast.ExprNode, otherCond []ast.ExprNode) {
Expand All @@ -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)
}
Expand All @@ -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
}
Expand Down
44 changes: 12 additions & 32 deletions optimizer/plan/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
}
Expand All @@ -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())
}
Expand All @@ -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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line should be removed.

p.SetFields(src.Fields())
return p
Expand All @@ -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
}
Expand All @@ -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
}
Expand Down Expand Up @@ -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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this line.

d.SetFields(src.Fields())
return d
Expand Down Expand Up @@ -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
Expand All @@ -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
}
Expand All @@ -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
}
Expand Down
Loading