Skip to content

Commit

Permalink
Copy expression types to avoid weight_strings and derived tables (#15069
Browse files Browse the repository at this point in the history
)
  • Loading branch information
wangweicugw authored Feb 2, 2024
1 parent b923e82 commit ea8a90d
Show file tree
Hide file tree
Showing 3 changed files with 214 additions and 9 deletions.
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
20 changes: 15 additions & 5 deletions go/vt/vtgate/planbuilder/operators/union_merging.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ 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"
"vitess.io/vitess/go/vt/vtgate/evalengine"
"vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext"
)

Expand Down Expand Up @@ -180,25 +183,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
192 changes: 188 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 @@ -1535,5 +1534,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"
]
}
}
]

0 comments on commit ea8a90d

Please sign in to comment.