Merge 'Fix EXISTS on LEFT JOIN null rows' from Duy Dang

Close #3890

Reviewed-by: Preston Thorpe <preston@turso.tech>

Closes #3914
This commit is contained in:
Preston Thorpe
2025-11-05 17:06:31 -05:00
committed by GitHub
2 changed files with 31 additions and 20 deletions

View File

@@ -718,25 +718,6 @@ pub fn open_loop(
}
}
for subquery in subqueries.iter_mut().filter(|s| !s.has_been_evaluated()) {
assert!(subquery.correlated, "subquery must be correlated");
let eval_at = subquery.get_eval_at(join_order)?;
if eval_at != EvalAt::Loop(join_index) {
continue;
}
let plan = subquery.consume_plan(eval_at);
emit_non_from_clause_subquery(
program,
t_ctx,
*plan,
&subquery.query_type,
subquery.correlated,
)?;
}
// First emit outer join conditions, if any.
emit_conditions(
program,
@@ -765,6 +746,25 @@ pub fn open_loop(
}
}
for subquery in subqueries.iter_mut().filter(|s| !s.has_been_evaluated()) {
assert!(subquery.correlated, "subquery must be correlated");
let eval_at = subquery.get_eval_at(join_order)?;
if eval_at != EvalAt::Loop(join_index) {
continue;
}
let plan = subquery.consume_plan(eval_at);
emit_non_from_clause_subquery(
program,
t_ctx,
*plan,
&subquery.query_type,
subquery.correlated,
)?;
}
// Now we can emit conditions from the WHERE clause.
// If the right table produces a NULL row, control jumps to the point where the match flag is set.
// The WHERE clause conditions may reference columns from that row, so they cannot be emitted

View File

@@ -120,6 +120,17 @@ do_execsql_test nested-subquery-cte {
select sub.loudest_hat from sub;
} {HAT!!!}
do_execsql_test_on_specific_db {:memory:} correlated-left-join-exists {
create table t(a);
create table s(a);
insert into t values (1);
select t.a
from t
left join s
on t.a = s.a
where exists (select 1 where s.a is null);
} {1}
do_execsql_test subquery-orderby-limit {
select upper(sub.loud_name) as loudest_name
from (
@@ -987,4 +998,4 @@ do_execsql_test_in_memory_any_error subquery-vector-in-function-call {
insert into t1 values (1);
insert into t2 values (1, 2);
select abs((select y, z from t2)) from t1;
}
}