Skip to content

Commit 6bc9ba7

Browse files
authored
Merge pull request #3135 from dolthub/angela/antijoin
include null values when evaluating anti joins created from `WHERE NOT EXISTS`
2 parents 66e9698 + 328e764 commit 6bc9ba7

File tree

10 files changed

+22777
-23955
lines changed

10 files changed

+22777
-23955
lines changed

enginetest/join_op_tests.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1921,6 +1921,18 @@ SELECT SUM(x) FROM xy WHERE x IN (
19211921
},
19221922
},
19231923
},
1924+
{
1925+
name: "where not exists",
1926+
setup: [][]string{
1927+
setup.XyData[0],
1928+
},
1929+
tests: []JoinOpTests{
1930+
{
1931+
Query: `select * from xy_hasnull x where not exists(select 1 from ab_hasnull a where a.b = x.y)`,
1932+
Expected: []sql.Row{{1, 0}, {3, nil}},
1933+
},
1934+
},
1935+
},
19241936
{
19251937
name: "multi-column merge join",
19261938
setup: [][]string{

enginetest/queries/imdb_plans.go

Lines changed: 22664 additions & 23880 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

enginetest/queries/integration_plans.go

Lines changed: 15 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

enginetest/queries/query_plans.go

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

enginetest/queries/tpch_plans.go

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sql/analyzer/indexed_joins.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,11 @@ func convertAntiToLeftJoin(m *memo.Memo) error {
561561
rightGrp := m.MemoizeProject(nil, anti.Right, projectExpressions)
562562

563563
// join is a new group
564-
joinGrp := m.MemoizeLeftJoin(nil, anti.Left, rightGrp, plan.JoinTypeLeftOuterExcludeNulls, anti.Filter)
564+
joinType := plan.JoinTypeLeftOuter
565+
if anti.Op.IsExcludeNulls() {
566+
joinType = plan.JoinTypeLeftOuterExcludeNulls
567+
}
568+
joinGrp := m.MemoizeLeftJoin(nil, anti.Left, rightGrp, joinType, anti.Filter)
565569

566570
// drop null projected columns on right table
567571
nullFilters := make([]sql.Expression, len(nullify))

sql/analyzer/unnest_exists_subqueries.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ func unnestExistSubqueries(ctx *sql.Context, scope *plan.Scope, a *Analyzer, fil
190190
switch joinType {
191191
case plan.JoinTypeAnti:
192192
cond := expression.NewLiteral(true, types.Boolean)
193-
ret = plan.NewAntiJoin(ret, s.inner, cond).WithComment(comment)
193+
ret = plan.NewAntiJoinIncludingNulls(ret, s.inner, cond).WithComment(comment)
194194
qFlags.Set(sql.QFlagInnerJoin)
195195
case plan.JoinTypeSemi:
196196
ret = plan.NewCrossJoin(ret, s.inner).WithComment(comment)
@@ -209,7 +209,7 @@ func unnestExistSubqueries(ctx *sql.Context, scope *plan.Scope, a *Analyzer, fil
209209

210210
switch joinType {
211211
case plan.JoinTypeAnti:
212-
ret = plan.NewAntiJoin(ret, s.inner, expression.JoinAnd(outerFilters...)).WithComment(comment)
212+
ret = plan.NewAntiJoinIncludingNulls(ret, s.inner, expression.JoinAnd(outerFilters...)).WithComment(comment)
213213
qFlags.Set(sql.QFlagInnerJoin)
214214
case plan.JoinTypeSemi:
215215
ret = plan.NewSemiJoin(ret, s.inner, expression.JoinAnd(outerFilters...)).WithComment(comment)

sql/memo/join_order_builder.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,7 @@ func (j *joinOrderBuilder) constructJoin(
811811
rel = &LeftJoin{b}
812812
case plan.JoinTypeSemi:
813813
rel = &SemiJoin{b}
814-
case plan.JoinTypeAnti:
814+
case plan.JoinTypeAnti, plan.JoinTypeAntiIncludeNulls:
815815
rel = &AntiJoin{b}
816816
case plan.JoinTypeLateralInner, plan.JoinTypeLateralCross,
817817
plan.JoinTypeLateralRight, plan.JoinTypeLateralLeft:
@@ -1428,7 +1428,7 @@ func getOpIdx(e *edge) int {
14281428
return 1
14291429
case plan.JoinTypeSemi:
14301430
return 2
1431-
case plan.JoinTypeAnti:
1431+
case plan.JoinTypeAnti, plan.JoinTypeAntiIncludeNulls:
14321432
return 3
14331433
case plan.JoinTypeLeftOuter:
14341434
return 4

0 commit comments

Comments
 (0)