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-18.0] Copy expression types to avoid weight_strings and derived tables (#15069) #15121

Closed
wants to merge 1 commit into from
Closed
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
11 changes: 11 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,17 @@ 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)]]")
})
if utils.BinaryIsAtLeastAtVersion(19, "vtgate") {
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
23 changes: 18 additions & 5 deletions go/vt/vtgate/planbuilder/operators/union_merging.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,16 @@ limitations under the License.
package operators

import (
"vitess.io/vitess/go/mysql/collations"
"vitess.io/vitess/go/sqltypes"
"vitess.io/vitess/go/vt/sqlparser"
"vitess.io/vitess/go/vt/vtgate/engine"
<<<<<<< HEAD
"vitess.io/vitess/go/vt/vtgate/planbuilder/operators/ops"
"vitess.io/vitess/go/vt/vtgate/planbuilder/operators/rewrite"
=======
"vitess.io/vitess/go/vt/vtgate/evalengine"
>>>>>>> ea8a90d093 (Copy expression types to avoid weight_strings and derived tables (#15069))
"vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext"
)

Expand Down Expand Up @@ -188,25 +194,32 @@ 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 {
types := []sqltypes.Type{rt.Type(), lt.Type()}
t := evalengine.AggregateTypes(types)
ctx.SemTable.ExprTypes[col] = evalengine.NewType(t, collations.Unknown)
}
ctx.SemTable.Recursive[col] = deps
}

Expand Down
256 changes: 252 additions & 4 deletions go/vt/vtgate/planbuilder/testdata/union_cases.json
Original file line number Diff line number Diff line change
Expand Up @@ -523,9 +523,8 @@
"Instructions": {
"OperatorType": "Distinct",
"Collations": [
"(0:1)"
"0"
],
"ResultColumns": 1,
"Inputs": [
{
"OperatorType": "Route",
Expand All @@ -534,8 +533,8 @@
"Name": "user",
"Sharded": true
},
"FieldQuery": "select `1`, weight_string(`1`) from (select 1 from dual where 1 != 1 union select null from dual where 1 != 1 union select 1.0 from dual where 1 != 1 union select '1' from dual where 1 != 1 union select 2 from dual where 1 != 1 union select 2.0 from `user` where 1 != 1) as dt where 1 != 1",
"Query": "select `1`, weight_string(`1`) from (select 1 from dual union select null from dual union select 1.0 from dual union select '1' from dual union select 2 from dual union select 2.0 from `user`) as dt",
"FieldQuery": "select 1 from dual where 1 != 1 union select null from dual where 1 != 1 union select 1.0 from dual where 1 != 1 union select '1' from dual where 1 != 1 union select 2 from dual where 1 != 1 union select 2.0 from `user` where 1 != 1",
"Query": "select 1 from dual union select null from dual union select 1.0 from dual union select '1' from dual union select 2 from dual union select 2.0 from `user`",
"Table": "`user`, dual"
}
]
Expand Down Expand Up @@ -1495,5 +1494,254 @@
"user.user"
]
}
<<<<<<< HEAD
=======
},
{
"comment": "join between two derived tables containing UNION",
"query": "select * from (select foo from user where bar = 12 union select foo from user where bar = 134) as t1 join (select bar from music where foo = 12 union select bar from music where foo = 1234) as t2 on t1.foo = t2.bar",
"plan": {
"QueryType": "SELECT",
"Original": "select * from (select foo from user where bar = 12 union select foo from user where bar = 134) as t1 join (select bar from music where foo = 12 union select bar from music where foo = 1234) as t2 on t1.foo = t2.bar",
"Instructions": {
"OperatorType": "Join",
"Variant": "Join",
"JoinColumnIndexes": "L:0,R:0",
"JoinVars": {
"t1_foo": 0
},
"TableName": "`user`_music",
"Inputs": [
{
"OperatorType": "Distinct",
"Collations": [
"(0:1)"
],
"Inputs": [
{
"OperatorType": "Route",
"Variant": "Scatter",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"FieldQuery": "select foo, weight_string(foo) from (select foo from `user` where 1 != 1 union select foo from `user` where 1 != 1) as dt where 1 != 1",
"Query": "select foo, weight_string(foo) from (select foo from `user` where bar = 12 union select foo from `user` where bar = 134) as dt",
"Table": "`user`"
}
]
},
{
"OperatorType": "Distinct",
"Collations": [
"(0:1)"
],
"Inputs": [
{
"OperatorType": "Route",
"Variant": "Scatter",
"Keyspace": {
"Name": "user",
"Sharded": true
},
"FieldQuery": "select bar, weight_string(bar) from (select bar from music where 1 != 1 union select bar from music where 1 != 1) as dt where 1 != 1",
"Query": "select bar, weight_string(bar) from (select bar from music where foo = 12 and bar = :t1_foo union select bar from music where foo = 1234 and bar = :t1_foo) as dt",
"Table": "music"
}
]
}
]
},
"TablesUsed": [
"user.music",
"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"
]
}
>>>>>>> ea8a90d093 (Copy expression types to avoid weight_strings and derived tables (#15069))
}
]
Loading