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

[release-16.0] fix: union distinct between unsharded route and sharded join (#12968) #12974

Merged
merged 1 commit into from Apr 26, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -83,3 +83,6 @@ venv

.scannerwork
report

# plan test output
/go/vt/vtgate/planbuilder/testdata/plan_test*
29 changes: 13 additions & 16 deletions go/vt/vtgate/planbuilder/operator_transformers.go
Expand Up @@ -464,25 +464,22 @@ func pushWeightStringForDistinct(ctx *plancontext.PlanningContext, plan logicalP
}
node.noNeedToTypeCheck = append(node.noNeedToTypeCheck, newOffset)
case *joinGen4:
lhsSolves := node.Left.ContainsTables()
rhsSolves := node.Right.ContainsTables()
expr := node.OutputColumns()[offset]
aliasedExpr, isAliased := expr.(*sqlparser.AliasedExpr)
if !isAliased {
return 0, vterrors.VT13001("cannot convert JOIN output columns to an aliased-expression")
}
deps := ctx.SemTable.RecursiveDeps(aliasedExpr.Expr)
joinOffset := node.Cols[offset]
switch {
case deps.IsSolvedBy(lhsSolves):
offset, err = pushWeightStringForDistinct(ctx, node.Left, offset)
node.Cols = append(node.Cols, -(offset + 1))
case deps.IsSolvedBy(rhsSolves):
offset, err = pushWeightStringForDistinct(ctx, node.Right, offset)
node.Cols = append(node.Cols, offset+1)
case joinOffset < 0:
offset, err = pushWeightStringForDistinct(ctx, node.Left, -(joinOffset + 1))
offset = -(offset + 1)
case joinOffset > 0:
offset, err = pushWeightStringForDistinct(ctx, node.Right, joinOffset-1)
offset = offset + 1
default:
return 0, vterrors.VT12001("push DISTINCT WEIGHT_STRING to both sides of the join")
return 0, vterrors.VT13001("wrong column offset in join plan to push DISTINCT WEIGHT_STRING")
}
newOffset = len(node.Cols) - 1
if err != nil {
return 0, err
}
newOffset = len(node.Cols)
node.Cols = append(node.Cols, offset)
default:
return 0, vterrors.VT13001(fmt.Sprintf("pushWeightStringForDistinct on %T", plan))
}
Expand Down
125 changes: 125 additions & 0 deletions go/vt/vtgate/planbuilder/testdata/union_cases.json
Expand Up @@ -2453,5 +2453,130 @@
"main.unsharded"
]
}
},
{
"comment": "union of unsharded route with sharded join with involvement of weight string",
"query": "select id, foo, bar from unsharded union select user.intcol, user.textcol2, authoritative.col2 from user join authoritative",
"v3-plan": {
"QueryType": "SELECT",
"Original": "select id, foo, bar from unsharded union select user.intcol, user.textcol2, authoritative.col2 from user join authoritative",
"Instructions": {
"OperatorType": "Distinct",
"Inputs": [
{
"OperatorType": "Concatenate",
"Inputs": [
{
"OperatorType": "Route",
"Variant": "Unsharded",
"Keyspace": {
"Name": "main",
"Sharded": false
},
"FieldQuery": "select id, foo, bar from unsharded where 1 != 1",
"Query": "select id, foo, bar from unsharded",
"Table": "unsharded"
},
{
"OperatorType": "Join",
"Variant": "Join",
"JoinColumnIndexes": "L:0,L:1,R:0",
"TableName": "`user`_authoritative",
"Inputs": [
{
"OperatorType": "Route",
"Variant": "Scatter",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"FieldQuery": "select `user`.intcol, `user`.textcol2 from `user` where 1 != 1",
"Query": "select `user`.intcol, `user`.textcol2 from `user`",
"Table": "`user`"
},
{
"OperatorType": "Route",
"Variant": "Scatter",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"FieldQuery": "select authoritative.col2 from authoritative where 1 != 1",
"Query": "select authoritative.col2 from authoritative",
"Table": "authoritative"
}
]
}
]
}
]
}
},
"gen4-plan": {
"QueryType": "SELECT",
"Original": "select id, foo, bar from unsharded union select user.intcol, user.textcol2, authoritative.col2 from user join authoritative",
"Instructions": {
"OperatorType": "Distinct",
"Collations": [
"(0:3)",
"(1:4)",
"(2:5)"
],
"ResultColumns": 3,
"Inputs": [
{
"OperatorType": "Concatenate",
"Inputs": [
{
"OperatorType": "Route",
"Variant": "Unsharded",
"Keyspace": {
"Name": "main",
"Sharded": false
},
"FieldQuery": "select id, foo, bar, weight_string(id), weight_string(foo), weight_string(bar) from unsharded where 1 != 1",
"Query": "select distinct id, foo, bar, weight_string(id), weight_string(foo), weight_string(bar) from unsharded",
"Table": "unsharded"
},
{
"OperatorType": "Join",
"Variant": "Join",
"JoinColumnIndexes": "L:0,L:1,R:0,L:2,L:3,R:1",
"TableName": "`user`_authoritative",
"Inputs": [
{
"OperatorType": "Route",
"Variant": "Scatter",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"FieldQuery": "select `user`.intcol, `user`.textcol2, weight_string(`user`.intcol), weight_string(`user`.textcol2) from `user` where 1 != 1",
"Query": "select `user`.intcol, `user`.textcol2, weight_string(`user`.intcol), weight_string(`user`.textcol2) from `user`",
"Table": "`user`"
},
{
"OperatorType": "Route",
"Variant": "Scatter",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"FieldQuery": "select authoritative.col2, weight_string(authoritative.col2) from authoritative where 1 != 1",
"Query": "select authoritative.col2, weight_string(authoritative.col2) from authoritative",
"Table": "authoritative"
}
]
}
]
}
]
},
"TablesUsed": [
"main.unsharded",
"user.authoritative",
"user.user"
]
}
}
]