diff --git a/enginetest/queries/script_queries.go b/enginetest/queries/script_queries.go index f4c7987e77..999dbb685e 100644 --- a/enginetest/queries/script_queries.go +++ b/enginetest/queries/script_queries.go @@ -14657,6 +14657,21 @@ select * from t1 except ( }, }, }, + { + // https://github.com/dolthub/dolt/issues/10258 + Name: "WHERE NOT EXISTS from empty view", + SetUpScript: []string{ + "CREATE TABLE t1(c0 boolean, c1 boolean);", + "insert into t1(c0) values (true), (false)", + "create view v0(c0) as select true having false", + }, + Assertions: []ScriptTestAssertion{ + { + Query: "SELECT * from t1 where not exists (select 1 from v0 where (case t1.c1 when false then v0.c0 else t1.c0 end)) order by c0", + Expected: []sql.Row{{0, nil}, {1, nil}}, + }, + }, + }, { // https://github.com/dolthub/dolt/issues/10246 Dialect: "mysql", diff --git a/sql/rowexec/join_iters.go b/sql/rowexec/join_iters.go index 1d46c86d8d..b9d4fe9ed2 100644 --- a/sql/rowexec/join_iters.go +++ b/sql/rowexec/join_iters.go @@ -247,7 +247,6 @@ func newExistsIter(ctx *sql.Context, b sql.NodeExecBuilder, j *plan.JoinNode, ro cond: j.Filter, scopeLen: j.ScopeLen, rowSize: rowSize, - nullRej: j.Filter != nil && plan.IsNullRejecting(j.Filter), }, nil } @@ -262,7 +261,6 @@ type existsIter struct { scopeLen int rowSize int typ plan.JoinType - nullRej bool rightIterNonEmpty bool } @@ -303,22 +301,7 @@ func (i *existsIter) Next(ctx *sql.Context) (sql.Row, error) { return nil, err } if plan.IsEmptyIter(rIter) { - switch { - case i.typ.IsSemi(): - // EXISTS with empty right is always false → skip this left row - nextState = esIncLeft - case i.typ.IsAnti(): - if i.nullRej { - // Filter is null-rejecting: need to run condition once with nil right so NULL can propagate - // and row may be excluded - nextState = esCompare - } else { - // Filter is not null-rejecting: no matches possible, row passes - nextState = esRet - } - default: - nextState = esCompare - } + nextState = esRightIterEOF } else { nextState = esIncRight }