diff --git a/go/test/endtoend/vtgate/queries/union/union_test.go b/go/test/endtoend/vtgate/queries/union/union_test.go index d382d039f02..1a1ae75297d 100644 --- a/go/test/endtoend/vtgate/queries/union/union_test.go +++ b/go/test/endtoend/vtgate/queries/union/union_test.go @@ -130,4 +130,11 @@ func TestUnion(t *testing.T) { if utils.BinaryIsAtLeastAtVersion(19, "vtgate") { mcmp.AssertMatches(`(SELECT id2,'a' from t1 where id1 = 1) union (SELECT 'a',id2 from t1 where id1 = 2)`, `[[VARCHAR("1") VARCHAR("a")] [VARCHAR("a") VARCHAR("2")]]`) } + mcmp.AssertMatches(`SELECT 1 from t1 UNION SELECT 2 from t1`, `[[INT64(1)] [INT64(2)]]`) + mcmp.AssertMatches(`SELECT 4 from t1 UNION SELECT 3 from t1`, `[[INT64(4)] [INT64(3)]]`) + mcmp.AssertMatches(`SELECT id1 from t1 UNION SELECT id2 from t1`, `[[INT64(1)] [INT64(2)]]`) + mcmp.AssertMatches(`SELECT 1 from t1 UNION SELECT id2 from t1`, `[[INT64(1)] [INT64(2)]]`) + mcmp.AssertMatches(`SELECT 3 from t1 UNION SELECT id2 from t1`, `[[INT64(3)] [INT64(1)] [INT64(2)]]`) + mcmp.AssertMatches(`SELECT id1 from t1 UNION SELECT 2 from t1`, `[[INT64(1)] [INT64(2)]]`) + mcmp.AssertMatches(`SELECT id1 from t1 UNION SELECT 3 from t1`, `[[INT64(1)] [INT64(2)] [INT64(3)]]`) } diff --git a/go/vt/vtgate/planbuilder/operators/union_merging.go b/go/vt/vtgate/planbuilder/operators/union_merging.go index 953d779c6a1..03ee75ea771 100644 --- a/go/vt/vtgate/planbuilder/operators/union_merging.go +++ b/go/vt/vtgate/planbuilder/operators/union_merging.go @@ -180,25 +180,27 @@ 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)) + ctx.SemTable.CopySemanticInfo(rae.Expr, col) + ctx.SemTable.CopySemanticInfo(lae.Expr, col) ctx.SemTable.Recursive[col] = deps } diff --git a/go/vt/vtgate/planbuilder/testdata/union_cases.json b/go/vt/vtgate/planbuilder/testdata/union_cases.json index 975b66bd6eb..33f308ee4a6 100644 --- a/go/vt/vtgate/planbuilder/testdata/union_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/union_cases.json @@ -373,9 +373,8 @@ "Instructions": { "OperatorType": "Distinct", "Collations": [ - "(0:1)" + "0" ], - "ResultColumns": 1, "Inputs": [ { "OperatorType": "Route", @@ -384,8 +383,8 @@ "Name": "user", "Sharded": true }, - "FieldQuery": "select id, weight_string(id) from (select id from `user` where 1 != 1 union select id from music where 1 != 1 union select 1 from dual where 1 != 1) as dt where 1 != 1", - "Query": "select id, weight_string(id) from (select id from `user` union select id from music union select 1 from dual) as dt", + "FieldQuery": "select id from `user` where 1 != 1 union select id from music where 1 != 1 union select 1 from dual where 1 != 1", + "Query": "select id from `user` union select id from music union select 1 from dual", "Table": "`user`, dual, music" } ] @@ -523,9 +522,8 @@ "Instructions": { "OperatorType": "Distinct", "Collations": [ - "(0:1)" + "0" ], - "ResultColumns": 1, "Inputs": [ { "OperatorType": "Route", @@ -534,8 +532,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" } ] @@ -836,9 +834,8 @@ { "OperatorType": "Distinct", "Collations": [ - "(0:1)" + "0" ], - "ResultColumns": 1, "Inputs": [ { "OperatorType": "Route", @@ -847,8 +844,8 @@ "Name": "user", "Sharded": true }, - "FieldQuery": "select id, weight_string(id) from (select id from `user` where 1 != 1 union select 3 from dual where 1 != 1) as dt where 1 != 1", - "Query": "select id, weight_string(id) from (select id from `user` union select 3 from dual limit :__upper_limit) as dt", + "FieldQuery": "select id from `user` where 1 != 1 union select 3 from dual where 1 != 1", + "Query": "select id from `user` union select 3 from dual limit :__upper_limit", "Table": "`user`, dual" } ] @@ -1045,7 +1042,7 @@ { "OperatorType": "Distinct", "Collations": [ - "(0:1)", + "0", "1" ], "Inputs": [ @@ -1535,5 +1532,95 @@ "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" + ], + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select col1 from `user` where 1 != 1 union select 3 from `user` where 1 != 1", + "Query": "select col1 from `user` union select 3 from `user`", + "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" + ], + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select 3 from `user` where 1 != 1 union select col1 from `user` where 1 != 1", + "Query": "select 3 from `user` union select col1 from `user`", + "Table": "`user`" + } + ] + }, + "TablesUsed": [ + "user.user" + ] + } } ]