Skip to content
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
2 changes: 1 addition & 1 deletion data/test/vtgate/filter_cases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -766,4 +766,4 @@
# but they refer to different things. The first reference is to the outermost query,
# and the second reference is to the the innermost 'from' subquery.
"select id2 from user uu where id in (select id from user where id = uu.id and user.col in (select col from (select id from user_extra where user_id = 5) uu where uu.user_id = uu.id))"
"unsupported: subquery and parent route to different shards"
"unsupported: UNION or subquery on different shards: vindex values are different"
2 changes: 1 addition & 1 deletion data/test/vtgate/schema_test.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"owner": "multicolvin"
},
"user_md5_index": {
"type": "hash_test"
"type": "unicode_loose_md5"
},
"music_user_map": {
"type": "lookup_test",
Expand Down
24 changes: 14 additions & 10 deletions data/test/vtgate/unsupported_cases.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Unions
"select * from user union select * from user_extra"
"unsupported: UNION on multi-shard queries"
"unsupported: UNION or subquery containing multi-shard queries"

# SET
"set a=1"
Expand Down Expand Up @@ -29,11 +29,11 @@

# union operations in subqueries (FROM)
"select * from (select * from user union all select * from user_extra) as t"
"unsupported: UNION on multi-shard queries"
"unsupported: UNION or subquery containing multi-shard queries"

# union operations in subqueries (expressions)
"select * from user where id in (select * from user union select * from user_extra)"
"unsupported: UNION on multi-shard queries"
"unsupported: UNION or subquery containing multi-shard queries"

# subquery with join primitive (expressions)
"select * from user where id in (select user.id from user join user_extra)"
Expand Down Expand Up @@ -77,11 +77,11 @@

# subquery does not depend on unique vindex of outer query
"select id from user where id in (select user_id from user_extra where user_extra.user_id = user.col)"
"unsupported: subquery does not depend on scatter outer query"
"unsupported: UNION or subquery containing multi-shard queries"

# subquery does not depend on scatter outer query
"select id from user where id in (select user_id from user_extra where user_extra.user_id = 4)"
"unsupported: subquery does not depend on scatter outer query"
"unsupported: UNION or subquery containing multi-shard queries"

# subquery depends on a cross-shard subquery
"select id from (select user.id, user.col from user join user_extra) as t where id in (select t.col from user)"
Expand All @@ -105,7 +105,7 @@

# subquery and outer query route to different shards
"select id from user where id = 5 and id in (select user_id from user_extra where user_extra.user_id = 4)"
"unsupported: subquery and parent route to different shards"
"unsupported: UNION or subquery on different shards: vindex values are different"

# last_insert_id for sharded keyspace
"select last_insert_id() from user"
Expand Down Expand Up @@ -433,7 +433,7 @@

# multi-shard union
"(select id from user union select id from music) union select 1 from dual"
"unsupported: UNION on multi-shard queries"
"unsupported: UNION or subquery containing multi-shard queries"

# multi-shard union
"select 1 from music union (select id from user union all select name from unsharded)"
Expand All @@ -445,15 +445,19 @@

# multi-shard union
"select id from user union all select id from music"
"unsupported: UNION on multi-shard queries"
"unsupported: UNION or subquery containing multi-shard queries"

# union with the same target shard because of vindex
"select * from music where id = 1 union select * from user where id = 1"
"unsupported: UNION or subquery on different shards: vindexes are different"

# union with different target shards
"select 1 from music where id = 1 union select 1 from music where id = 2"
"unsupported: UNION queries with different target shards"
"unsupported: UNION or subquery on different shards: vindex values are different"

# Union all
"select col1, col2 from user union all select col1, col2 from user_extra"
"unsupported: UNION on multi-shard queries"
"unsupported: UNION or subquery containing multi-shard queries"

"(select user.id, user.name from user join user_extra where user_extra.extra = 'asdf') union select 'b','c' from user"
"unsupported construct: SELECT of UNION is non-trivial"
Expand Down
6 changes: 2 additions & 4 deletions go/vt/vtgate/planbuilder/from.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,10 +276,8 @@ func (pb *primitiveBuilder) join(rpb *primitiveBuilder, ajoin *sqlparser.JoinTab
}

// Both l & r routes point to the same shard.
if lRoute.ERoute.Opcode == engine.SelectEqualUnique && rRoute.ERoute.Opcode == engine.SelectEqualUnique {
if valEqual(lRoute.condition, rRoute.condition) {
return pb.mergeRoutes(rpb, ajoin)
}
if lRoute.isSameShardedRoute(rRoute) == nil {
return pb.mergeRoutes(rpb, ajoin)
}
}

Expand Down
22 changes: 12 additions & 10 deletions go/vt/vtgate/planbuilder/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -622,14 +622,7 @@ func (rb *route) SubqueryCanMerge(pb *primitiveBuilder, inner *route) error {
default:
return errors.New("unsupported: scatter subquery")
}

if rb.ERoute.Opcode != engine.SelectEqualUnique {
return errors.New("unsupported: subquery does not depend on scatter outer query")
}
if !valEqual(rb.condition, inner.condition) {
return errors.New("unsupported: subquery and parent route to different shards")
}
return nil
return rb.isSameShardedRoute(inner)
}

// UnionCanMerge returns nil if the supplied route that represents
Expand All @@ -654,12 +647,21 @@ func (rb *route) UnionCanMerge(right *route) error {
}
return errIntermixingUnsupported
}
return rb.isSameShardedRoute(right)
}

// isSameShardedRoute returns nil if the supplied route has
// the same single shard target as the current route. If not, it
// returns an appropriate error.
func (rb *route) isSameShardedRoute(right *route) error {
if rb.ERoute.Opcode != engine.SelectEqualUnique || right.ERoute.Opcode != engine.SelectEqualUnique {
return errors.New("unsupported: UNION on multi-shard queries")
return errors.New("unsupported: UNION or subquery containing multi-shard queries")
}
if rb.ERoute.Vindex != right.ERoute.Vindex {
return errors.New("unsupported: UNION or subquery on different shards: vindexes are different")
}
if !valEqual(rb.condition, right.condition) {
return errors.New("unsupported: UNION queries with different target shards")
return errors.New("unsupported: UNION or subquery on different shards: vindex values are different")
}
return nil
}
Expand Down