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

routing: improve dual and left joins #5551

Merged
merged 1 commit into from
Dec 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ require (
github.com/golang/mock v1.3.1
github.com/golang/protobuf v1.3.2
github.com/golang/snappy v0.0.0-20170215233205-553a64147049
github.com/google/btree v1.0.0 // indirect
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf // indirect
github.com/gorilla/websocket v0.0.0-20160912153041-2d1e4548da23
github.com/grpc-ecosystem/go-grpc-middleware v1.1.0
Expand All @@ -50,8 +49,6 @@ require (
github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.1.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/olekukonko/tablewriter v0.0.0-20160115111002-cca8bbc07984
github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02
github.com/opentracing/opentracing-go v1.1.0
Expand Down
24 changes: 14 additions & 10 deletions go/vt/vtgate/planbuilder/route_option.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,8 @@ func (ro *routeOption) JoinCanMerge(pb *primitiveBuilder, rro *routeOption, ajoi
}

func (ro *routeOption) MergeJoin(rro *routeOption, isLeftJoin bool) {
ro.merge(rro)
ro.vschemaTable = nil
ro.substitutions = append(ro.substitutions, rro.substitutions...)
if isLeftJoin {
return
}
// Add RHS vindexes only if it's not a left join.
for c, v := range rro.vindexMap {
if ro.vindexMap == nil {
ro.vindexMap = make(map[*column]vindexes.SingleColumn)
Expand All @@ -101,6 +97,16 @@ func (ro *routeOption) MergeJoin(rro *routeOption, isLeftJoin bool) {
}
}

// merge merges two routeOptions. If the LHS (ro) is a SelectReference,
// then the RHS option values supersede LHS.
func (ro *routeOption) merge(rro *routeOption) {
if ro.eroute.Opcode == engine.SelectReference {
// Swap the values and then merge.
*ro, *rro = *rro, *ro
}
ro.substitutions = append(ro.substitutions, rro.substitutions...)
}

func (ro *routeOption) SubqueryCanMerge(pb *primitiveBuilder, inner *routeOption) bool {
return ro.canMerge(inner, func() bool {
switch vals := inner.condition.(type) {
Expand All @@ -114,16 +120,16 @@ func (ro *routeOption) SubqueryCanMerge(pb *primitiveBuilder, inner *routeOption
}

func (ro *routeOption) MergeSubquery(subqueryOption *routeOption) {
ro.substitutions = append(ro.substitutions, subqueryOption.substitutions...)
ro.merge(subqueryOption)
}

func (ro *routeOption) UnionCanMerge(rro *routeOption) bool {
return ro.canMerge(rro, func() bool { return false })
}

func (ro *routeOption) MergeUnion(rro *routeOption) {
ro.merge(rro)
ro.vschemaTable = nil
ro.substitutions = append(ro.substitutions, rro.substitutions...)
}

func (ro *routeOption) SubqueryToTable(rb *route, vindexMap map[*column]vindexes.SingleColumn) {
Expand All @@ -149,9 +155,7 @@ func (ro *routeOption) canMerge(rro *routeOption, customCheck func() bool) bool
return true
}
case engine.SelectReference:
// TODO(sougou): this can be changed to true, but we'll have
// to merge against rro insteal of ro.
return false
return true
case engine.SelectNext:
return false
}
Expand Down
6 changes: 5 additions & 1 deletion go/vt/vtgate/planbuilder/testdata/filter_cases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -233,13 +233,17 @@
{
"Original": "select user_extra.id from user left join user_extra on user.id = user_extra.user_id where user_extra.user_id = 5",
"Instructions": {
"Opcode": "SelectScatter",
"Opcode": "SelectEqualUnique",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"Query": "select user_extra.id from user left join user_extra on user.id = user_extra.user_id where user_extra.user_id = 5",
"FieldQuery": "select user_extra.id from user left join user_extra on user.id = user_extra.user_id where 1 != 1",
"Vindex": "user_index",
"Values": [
5
],
"Table": "user"
}
}
Expand Down
32 changes: 8 additions & 24 deletions go/vt/vtgate/planbuilder/testdata/from_cases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -927,35 +927,19 @@
}
}

# reference table doesn't merge with other opcodes yet.
# reference table can merge with other opcodes left to right.
"select ref.col from ref join user"
{
"Original": "select ref.col from ref join user",
"Instructions": {
"Opcode": "Join",
"Left": {
"Opcode": "SelectReference",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"Query": "select ref.col from ref",
"FieldQuery": "select ref.col from ref where 1 != 1",
"Table": "ref"
},
"Right": {
"Opcode": "SelectScatter",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"Query": "select 1 from user",
"FieldQuery": "select 1 from user where 1 != 1",
"Table": "user"
"Opcode": "SelectScatter",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"Cols": [
-1
]
"Query": "select ref.col from ref join user",
"FieldQuery": "select ref.col from ref join user where 1 != 1",
"Table": "user"
}
}

Expand Down
5 changes: 0 additions & 5 deletions go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,3 @@

"select func(keyspace_id) from user_index where id = :id"
"unsupported: expression on results of a vindex function"

# Multi-table unique vindex constraint on left table of left join, two levels of join, simple aggregation
# This should work, but doesn't. See https://github.com/vitessio/vitess/issues/4772
"select user.id, count(*) from user left join user_extra ue1 on user.id = ue1.user_id left join user_extra ue2 on ue1.user_id = ue2.user_id group by user.id"
"unsupported: cross-shard query with aggregates"