Skip to content

[release-18.0] In the same sqltypes.Type, Copy expression types to avoid weight_strings and derived tables (#15069) #15129

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

Merged
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
9 changes: 9 additions & 0 deletions go/test/endtoend/vtgate/queries/union/union_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ func TestUnionDistinct(t *testing.T) {
t.Skip()
mcmp.AssertMatches("select 1 from dual where 1 IN (select 1 as col union select 2)", "[[INT64(1)]]")
})
mcmp.AssertMatches(`SELECT 1 from t1 UNION SELECT 2 from t1`, `[[INT64(1)] [INT64(2)]]`)
mcmp.AssertMatches(`SELECT 5 from t1 UNION SELECT 6 from t1`, `[[INT64(5)] [INT64(6)]]`)
mcmp.AssertMatchesNoOrder(`SELECT id1 from t1 UNION SELECT id2 from t1`, `[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(4)]]`)
mcmp.AssertMatchesNoOrder(`SELECT 1 from t1 UNION SELECT id2 from t1`, `[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(4)]]`)
mcmp.AssertMatchesNoOrder(`SELECT 5 from t1 UNION SELECT id2 from t1`, `[[INT64(5)] [INT64(1)] [INT64(2)] [INT64(3)] [INT64(4)]]`)
mcmp.AssertMatchesNoOrder(`SELECT id1 from t1 UNION SELECT 2 from t1`, `[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(4)]]`)
mcmp.AssertMatchesNoOrder(`SELECT id1 from t1 UNION SELECT 5 from t1`, `[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(4)] [INT64(5)]]`)
mcmp.Exec(`select curdate() from t1 union select 3 from t1`)
mcmp.Exec(`select curdate() from t1 union select id1 from t1`)
})

}
Expand Down
16 changes: 11 additions & 5 deletions go/vt/vtgate/planbuilder/operators/union_merging.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,25 +188,31 @@ func createMergedUnion(
cols := make(sqlparser.SelectExprs, len(lhsExprs))
noDeps := len(lhsExprs) != len(rhsExprs)
for idx, col := range lhsExprs {
ae, ok := col.(*sqlparser.AliasedExpr)
lae, ok := col.(*sqlparser.AliasedExpr)
if !ok {
cols[idx] = col
noDeps = true
continue
}
col := sqlparser.NewColName(ae.ColumnName())
col := sqlparser.NewColName(lae.ColumnName())
cols[idx] = aeWrap(col)
if noDeps {
continue
}

deps := ctx.SemTable.RecursiveDeps(ae.Expr)
ae, ok = rhsExprs[idx].(*sqlparser.AliasedExpr)
deps := ctx.SemTable.RecursiveDeps(lae.Expr)
rae, ok := rhsExprs[idx].(*sqlparser.AliasedExpr)
if !ok {
noDeps = true
continue
}
deps = deps.Merge(ctx.SemTable.RecursiveDeps(ae.Expr))
deps = deps.Merge(ctx.SemTable.RecursiveDeps(rae.Expr))
rt, _, foundR := ctx.SemTable.TypeForExpr(rae.Expr)
lt, _, foundL := ctx.SemTable.TypeForExpr(lae.Expr)
if foundR && foundL && rt == lt {
ctx.SemTable.CopySemanticInfo(rae.Expr, col)
ctx.SemTable.CopySemanticInfo(lae.Expr, col)
}
ctx.SemTable.Recursive[col] = deps
}

Expand Down
185 changes: 185 additions & 0 deletions go/vt/vtgate/planbuilder/testdata/union_cases.json
Original file line number Diff line number Diff line change
Expand Up @@ -1495,5 +1495,190 @@
"user.user"
]
}
},
{
"comment": "Select literals from table union Select literals from table",
"query": "SELECT 1 from user UNION SELECT 2 from user",
"plan": {
"QueryType": "SELECT",
"Original": "SELECT 1 from user UNION SELECT 2 from user",
"Instructions": {
"OperatorType": "Distinct",
"Collations": [
"0"
],
"Inputs": [
{
"OperatorType": "Route",
"Variant": "Scatter",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"FieldQuery": "select 1 from `user` where 1 != 1 union select 2 from `user` where 1 != 1",
"Query": "select 1 from `user` union select 2 from `user`",
"Table": "`user`"
}
]
},
"TablesUsed": [
"user.user"
]
}
},
{
"comment": "Select column from table union Select literals from table",
"query": "select col1 from user union select 3 from user",
"plan": {
"QueryType": "SELECT",
"Original": "select col1 from user union select 3 from user",
"Instructions": {
"OperatorType": "Distinct",
"Collations": [
"(0:1)"
],
"ResultColumns": 1,
"Inputs": [
{
"OperatorType": "Route",
"Variant": "Scatter",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"FieldQuery": "select col1, weight_string(col1) from (select col1 from `user` where 1 != 1 union select 3 from `user` where 1 != 1) as dt where 1 != 1",
"Query": "select col1, weight_string(col1) from (select col1 from `user` union select 3 from `user`) as dt",
"Table": "`user`"
}
]
},
"TablesUsed": [
"user.user"
]
}
},
{
"comment": "Select literals from table union Select column from table",
"query": "select 3 from user union select col1 from user",
"plan": {
"QueryType": "SELECT",
"Original": "select 3 from user union select col1 from user",
"Instructions": {
"OperatorType": "Distinct",
"Collations": [
"(0:1)"
],
"ResultColumns": 1,
"Inputs": [
{
"OperatorType": "Route",
"Variant": "Scatter",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"FieldQuery": "select `3`, weight_string(`3`) from (select 3 from `user` where 1 != 1 union select col1 from `user` where 1 != 1) as dt where 1 != 1",
"Query": "select `3`, weight_string(`3`) from (select 3 from `user` union select col1 from `user`) as dt",
"Table": "`user`"
}
]
},
"TablesUsed": [
"user.user"
]
}
},
{
"comment": "Select literals from table union Select now() from table",
"query": "select 3 from user union select now() from user",
"plan": {
"QueryType": "SELECT",
"Original": "select 3 from user union select now() from user",
"Instructions": {
"OperatorType": "Distinct",
"Collations": [
"(0:1)"
],
"ResultColumns": 1,
"Inputs": [
{
"OperatorType": "Route",
"Variant": "Scatter",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"FieldQuery": "select `3`, weight_string(`3`) from (select 3 from `user` where 1 != 1 union select now() from `user` where 1 != 1) as dt where 1 != 1",
"Query": "select `3`, weight_string(`3`) from (select 3 from `user` union select now() from `user`) as dt",
"Table": "`user`"
}
]
},
"TablesUsed": [
"user.user"
]
}
},
{
"comment": "Select now() from table union Select literals from table",
"query": "select now() from user union select 3 from user",
"plan": {
"QueryType": "SELECT",
"Original": "select now() from user union select 3 from user",
"Instructions": {
"OperatorType": "Distinct",
"Collations": [
"(0:1)"
],
"ResultColumns": 1,
"Inputs": [
{
"OperatorType": "Route",
"Variant": "Scatter",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"FieldQuery": "select `now()`, weight_string(`now()`) from (select now() from `user` where 1 != 1 union select 3 from `user` where 1 != 1) as dt where 1 != 1",
"Query": "select `now()`, weight_string(`now()`) from (select now() from `user` union select 3 from `user`) as dt",
"Table": "`user`"
}
]
},
"TablesUsed": [
"user.user"
]
}
},
{
"comment": "Select now() from table union Select column from table",
"query": "select now() from user union select id from user",
"plan": {
"QueryType": "SELECT",
"Original": "select now() from user union select id from user",
"Instructions": {
"OperatorType": "Distinct",
"Collations": [
"(0:1)"
],
"ResultColumns": 1,
"Inputs": [
{
"OperatorType": "Route",
"Variant": "Scatter",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"FieldQuery": "select `now()`, weight_string(`now()`) from (select now() from `user` where 1 != 1 union select id from `user` where 1 != 1) as dt where 1 != 1",
"Query": "select `now()`, weight_string(`now()`) from (select now() from `user` union select id from `user`) as dt",
"Table": "`user`"
}
]
},
"TablesUsed": [
"user.user"
]
}
}
]