Skip to content

Commit f485924

Browse files
authored
Merge pull request #3196 from dolthub/angela/fullouterjoin
Do not push down filters for Full Outer joins
2 parents f65884e + a3ee480 commit f485924

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

enginetest/join_op_tests.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2112,6 +2112,47 @@ WHERE
21122112
},
21132113
},
21142114
},
2115+
{
2116+
// https://github.com/dolthub/dolt/issues/9793
2117+
name: "outer join on false",
2118+
setup: [][]string{
2119+
{
2120+
"create table t1(c0 int)",
2121+
"create table t2(c0 int)",
2122+
"insert into t1 values (1)",
2123+
"insert into t2 values (1)",
2124+
},
2125+
},
2126+
tests: []JoinOpTests{
2127+
{
2128+
Query: "select * from t1 full outer join t2 on false",
2129+
Expected: []sql.Row{
2130+
{1, nil},
2131+
{nil, 1},
2132+
},
2133+
},
2134+
{
2135+
Query: "select * from t1 full outer join t2 on false where t2.c0 is not null and t1.c0 is not null",
2136+
Expected: []sql.Row{},
2137+
},
2138+
{
2139+
Query: "select * from t1 left outer join t2 on false",
2140+
Expected: []sql.Row{{1, nil}},
2141+
},
2142+
{
2143+
Query: "select * from t1 left outer join t2 on false where t2.c0 is not null",
2144+
Expected: []sql.Row{},
2145+
},
2146+
{
2147+
Query: "select * from t1 right outer join t2 on false",
2148+
Expected: []sql.Row{{nil, 1}},
2149+
},
2150+
{
2151+
Query: "select * from t1 right outer join t2 on false where t1.c0 is not null",
2152+
Expected: []sql.Row{},
2153+
},
2154+
},
2155+
},
21152156
}
21162157

21172158
var rangeJoinOpTests = []JoinOpTests{

sql/analyzer/pushdown.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,10 @@ func canDoPushdown(n sql.Node) bool {
157157
return true
158158
}
159159

160-
// Pushing down a filter is incompatible with the secondary table in a Left
161-
// or Right join. If we push a predicate on the secondary table below the
162-
// join, we end up not evaluating it in all cases (since the secondary table
163-
// result is sometimes null in these types of joins). It must be evaluated
164-
// only after the join result is computed.
160+
// Pushing down a filter is incompatible with the secondary table in a Left or Right join. If we push a predicate on the
161+
// secondary table below the join, we end up not evaluating it in all cases (since the secondary table result is
162+
// sometimes null in these types of joins). It must be evaluated only after the join result is computed. This is also
163+
// true with both tables in a Full Outer join, since either table result could be null.
165164
func filterPushdownChildSelector(c transform.Context) bool {
166165
switch c.Node.(type) {
167166
case *plan.Limit:
@@ -178,6 +177,8 @@ func filterPushdownChildSelector(c transform.Context) bool {
178177
return false
179178
case *plan.JoinNode:
180179
switch {
180+
case n.Op.IsFullOuter():
181+
return false
181182
case n.Op.IsMerge():
182183
return false
183184
case n.Op.IsLookup():

0 commit comments

Comments
 (0)