Skip to content

Commit 84406b0

Browse files
Fix cross shard/keyspace joins with derived tables containing a UNION. (#19046)
Signed-off-by: Arthur Schreiber <arthur@planetscale.com>
1 parent ba2028e commit 84406b0

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

go/vt/vtgate/planbuilder/operators/union.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"vitess.io/vitess/go/slice"
2424
"vitess.io/vitess/go/vt/sqlparser"
2525
"vitess.io/vitess/go/vt/vterrors"
26+
"vitess.io/vitess/go/vt/vtgate/planbuilder/operators/predicates"
2627
"vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext"
2728
)
2829

@@ -103,6 +104,11 @@ func (u *Union) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Ex
103104
offsets[ae.ColumnName()] = i
104105
}
105106

107+
if jp, ok := expr.(*predicates.JoinPredicate); ok {
108+
expr = jp.Current()
109+
ctx.PredTracker.Skip(jp.ID)
110+
}
111+
106112
needsFilter, exprPerSource := u.predicatePerSource(expr, offsets)
107113
if needsFilter {
108114
return newFilter(u, expr)
@@ -118,6 +124,7 @@ func (u *Union) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Ex
118124
func (u *Union) predicatePerSource(expr sqlparser.Expr, offsets map[string]int) (bool, []sqlparser.Expr) {
119125
needsFilter := false
120126
exprPerSource := make([]sqlparser.Expr, len(u.Sources))
127+
121128
for i := range u.Sources {
122129
predicate := sqlparser.CopyOnRewrite(expr, nil, func(cursor *sqlparser.CopyOnWriteCursor) {
123130
col, ok := cursor.Node().(*sqlparser.ColName)
@@ -137,11 +144,13 @@ func (u *Union) predicatePerSource(expr sqlparser.Expr, offsets map[string]int)
137144
if !ok {
138145
panic(vterrors.VT09015())
139146
}
147+
140148
cursor.Replace(ae.Expr)
141149
}, nil).(sqlparser.Expr)
142150

143151
exprPerSource[i] = predicate
144152
}
153+
145154
return needsFilter, exprPerSource
146155
}
147156

go/vt/vtgate/planbuilder/testdata/union_cases.json

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2067,6 +2067,76 @@
20672067
"user.user"
20682068
]
20692069
}
2070+
},
2071+
{
2072+
"comment": "join with derived table containing UNION with aliased columns across different keyspaces",
2073+
"query": "select u.id from user as u join (select id as pid from user where id = 1 union select id as pid from unsharded where id = 1) as i on u.id = i.pid",
2074+
"plan": {
2075+
"Type": "Join",
2076+
"QueryType": "SELECT",
2077+
"Original": "select u.id from user as u join (select id as pid from user where id = 1 union select id as pid from unsharded where id = 1) as i on u.id = i.pid",
2078+
"Instructions": {
2079+
"OperatorType": "Join",
2080+
"Variant": "Join",
2081+
"JoinColumnIndexes": "L:0",
2082+
"JoinVars": {
2083+
"u_id": 0
2084+
},
2085+
"Inputs": [
2086+
{
2087+
"OperatorType": "Route",
2088+
"Variant": "Scatter",
2089+
"Keyspace": {
2090+
"Name": "user",
2091+
"Sharded": true
2092+
},
2093+
"FieldQuery": "select u.id from `user` as u where 1 != 1",
2094+
"Query": "select u.id from `user` as u"
2095+
},
2096+
{
2097+
"OperatorType": "Distinct",
2098+
"Collations": [
2099+
"(0:1)"
2100+
],
2101+
"Inputs": [
2102+
{
2103+
"OperatorType": "Concatenate",
2104+
"Inputs": [
2105+
{
2106+
"OperatorType": "Route",
2107+
"Variant": "EqualUnique",
2108+
"Keyspace": {
2109+
"Name": "user",
2110+
"Sharded": true
2111+
},
2112+
"FieldQuery": "select dt.c0 as pid, weight_string(dt.c0) from (select id as pid from `user` where 1 != 1) as dt(c0) where 1 != 1",
2113+
"Query": "select dt.c0 as pid, weight_string(dt.c0) from (select distinct id as pid from `user` where id = 1 and id = :u_id) as dt(c0)",
2114+
"Values": [
2115+
":u_id"
2116+
],
2117+
"Vindex": "user_index"
2118+
},
2119+
{
2120+
"OperatorType": "Route",
2121+
"Variant": "Unsharded",
2122+
"Keyspace": {
2123+
"Name": "main",
2124+
"Sharded": false
2125+
},
2126+
"FieldQuery": "select dt.c0 as pid, weight_string(dt.c0) from (select id as pid from unsharded where 1 != 1) as dt(c0) where 1 != 1",
2127+
"Query": "select dt.c0 as pid, weight_string(dt.c0) from (select distinct id as pid from unsharded where id = 1 and id = :u_id) as dt(c0)"
2128+
}
2129+
]
2130+
}
2131+
]
2132+
}
2133+
]
2134+
},
2135+
"TablesUsed": [
2136+
"main.unsharded",
2137+
"user.user"
2138+
]
2139+
}
20702140
}
20712141

20722142
]

0 commit comments

Comments
 (0)