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

fix merging dba query as a subquery both in v3 and gen4 #8871

Merged
merged 2 commits into from
Sep 23, 2021
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
12 changes: 12 additions & 0 deletions go/vt/vtgate/planbuilder/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,18 @@ func (rb *route) Inputs() []logicalPlan {
// with the outer route.
func (rb *route) MergeSubquery(pb *primitiveBuilder, inner *route) bool {
if rb.SubqueryCanMerge(pb, inner) {
if inner.eroute.Opcode == engine.SelectDBA && (len(inner.eroute.SysTableTableName) > 0 || len(inner.eroute.SysTableTableSchema) > 0) {
switch rb.eroute.Opcode {
case engine.SelectDBA, engine.SelectReference:
rb.eroute.SysTableTableSchema = append(rb.eroute.SysTableTableSchema, inner.eroute.SysTableTableSchema...)
for k, v := range inner.eroute.SysTableTableName {
rb.eroute.SysTableTableName[k] = v
}
rb.eroute.Opcode = engine.SelectDBA
default:
return false
}
}
rb.substitutions = append(rb.substitutions, inner.substitutions...)
inner.Redirect = rb
return true
Expand Down
9 changes: 7 additions & 2 deletions go/vt/vtgate/planbuilder/route_planning.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func optimizeSubQuery(ctx *planningContext, op *abstract.SubQuery) (queryTree, e

preds := inner.Inner.UnsolvedPredicates(ctx.semTable)
merger := func(a, b *routeTree) (*routeTree, error) {
return mergeSubQuery(ctx, a, inner)
return mergeSubQuery(ctx, a, b, inner)
}

merged, err := tryMergeSubQuery(ctx, outerTree, treeInner, inner, preds, merger)
Expand Down Expand Up @@ -279,7 +279,7 @@ func rewriteSubqueryDependenciesForJoin(ctx *planningContext, otherTree queryTre
return rewriteError
}

func mergeSubQuery(ctx *planningContext, outer *routeTree, subq *abstract.SubQueryInner) (*routeTree, error) {
func mergeSubQuery(ctx *planningContext, outer *routeTree, inner *routeTree, subq *abstract.SubQueryInner) (*routeTree, error) {
ctx.sqToReplace[subq.ArgName] = subq.SelectStatement
// go over the subquery and add its tables to the one's solved by the route it is merged with
// this is needed to so that later when we try to push projections, we get the correct
Expand All @@ -294,6 +294,11 @@ func mergeSubQuery(ctx *planningContext, outer *routeTree, subq *abstract.SubQue
if err != nil {
return nil, err
}
outer.SysTableTableSchema = append(outer.SysTableTableSchema, inner.SysTableTableSchema...)
for k, v := range inner.SysTableTableName {
outer.SysTableTableName[k] = v
}

err = outer.resetRoutingSelections(ctx)
if err != nil {
return nil, err
Expand Down
55 changes: 55 additions & 0 deletions go/vt/vtgate/planbuilder/testdata/sysschema_default.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,58 @@ Gen4 plan same as above
"Table": "information_schema.`columns`, information_schema.`tables`"
}
}

# system schema query as a subquery
"SELECT (SELECT 1 FROM information_schema.schemata WHERE schema_name='MyDatabase' LIMIT 1);"
{
"QueryType": "SELECT",
"Original": "SELECT (SELECT 1 FROM information_schema.schemata WHERE schema_name='MyDatabase' LIMIT 1);",
"Instructions": {
"OperatorType": "Route",
"Variant": "SelectDBA",
"Keyspace": {
"Name": "main",
"Sharded": false
},
"FieldQuery": "select (select 1 from information_schema.schemata where 1 != 1) from dual where 1 != 1",
"Query": "select (select 1 from information_schema.schemata where schema_name = :__vtschemaname limit 1) from dual",
"SysTableTableSchema": "[VARBINARY(\"MyDatabase\")]",
"Table": "dual"
}
}
Gen4 plan same as above

# system schema query as a derived table
"SELECT * from (SELECT 1 FROM information_schema.schemata WHERE schema_name='MyDatabase' LIMIT 1) x"
{
"QueryType": "SELECT",
"Original": "SELECT * from (SELECT 1 FROM information_schema.schemata WHERE schema_name='MyDatabase' LIMIT 1) x",
"Instructions": {
"OperatorType": "Route",
"Variant": "SelectDBA",
"Keyspace": {
"Name": "main",
"Sharded": false
},
"FieldQuery": "select * from (select 1 from information_schema.schemata where 1 != 1) as x where 1 != 1",
"Query": "select * from (select 1 from information_schema.schemata where schema_name = :__vtschemaname limit 1) as x",
"SysTableTableSchema": "[VARBINARY(\"MyDatabase\")]",
"Table": "information_schema.schemata"
}
}
{
"QueryType": "SELECT",
"Original": "SELECT * from (SELECT 1 FROM information_schema.schemata WHERE schema_name='MyDatabase' LIMIT 1) x",
"Instructions": {
"OperatorType": "Route",
"Variant": "SelectDBA",
"Keyspace": {
"Name": "main",
"Sharded": false
},
"FieldQuery": "select x.`1` from (select 1 from information_schema.schemata where 1 != 1) as x where 1 != 1",
"Query": "select x.`1` from (select 1 from information_schema.schemata where schema_name = :__vtschemaname limit 1) as x",
"SysTableTableSchema": "[VARBINARY(\"MyDatabase\")]",
"Table": "information_schema.schemata"
}
}