diff --git a/velox/exec/MergeJoin.cpp b/velox/exec/MergeJoin.cpp index 194be412df52..08359dd05ca9 100644 --- a/velox/exec/MergeJoin.cpp +++ b/velox/exec/MergeJoin.cpp @@ -646,7 +646,13 @@ RowVectorPtr MergeJoin::getOutput() { // No rows survived the filter. Get more rows. continue; } else if (isAntiJoin(joinType_)) { - return filterOutputForAntiJoin(output); + output = filterOutputForAntiJoin(output); + if (output) { + return output; + } + + // No rows survived the filter for anti join. Get more rows. + continue; } else { return output; } diff --git a/velox/exec/tests/MergeJoinTest.cpp b/velox/exec/tests/MergeJoinTest.cpp index a91e62ca7b17..48f1e5700a2d 100644 --- a/velox/exec/tests/MergeJoinTest.cpp +++ b/velox/exec/tests/MergeJoinTest.cpp @@ -770,6 +770,38 @@ TEST_F(MergeJoinTest, antiJoinWithFilter) { "SELECT t0 FROM t WHERE NOT exists (select 1 from u where t0 = u0 AND t.t0 > 2 ) "); } +TEST_F(MergeJoinTest, antiJoinFailed) { + auto size = 1'00; + auto left = makeRowVector( + {"t0"}, {makeFlatVector(size, [](auto row) { return row; })}); + + auto right = makeRowVector( + {"u0"}, {makeFlatVector(size, [](auto row) { return row; })}); + + createDuckDbTable("t", {left}); + createDuckDbTable("u", {right}); + + // Anti join. + auto planNodeIdGenerator = std::make_shared(); + auto plan = + PlanBuilder(planNodeIdGenerator) + .values(split(left, 10)) + .orderBy({"t0"}, false) + .mergeJoin( + {"t0"}, + {"u0"}, + PlanBuilder(planNodeIdGenerator).values({right}).planNode(), + "", + {"t0"}, + core::JoinType::kAnti) + .planNode(); + + AssertQueryBuilder(plan, duckDbQueryRunner_) + .config(core::QueryConfig::kMaxOutputBatchRows, "10") + .assertResults( + "SELECT t0 FROM t WHERE NOT exists (select 1 from u where t0 = u0) "); +} + TEST_F(MergeJoinTest, antiJoinWithTwoJoinKeys) { auto left = makeRowVector( {"a", "b"},