linkrs_query/executor/streaming/subquery.rs
1//! Expression-level subquery execution.
2//!
3//! EXISTS / IN subqueries at non-conjunctive expression positions (WHERE
4//! residual, RETURN, HAVING, WITH assignments, ...) are compiled at planning
5//! time by `plan_expression_subqueries` into standalone sub-plans. Each
6//! compiled subquery becomes a [`SubqueryRunnerSpec`] on the hosting
7//! Filter/Project/Assign arena spec; the materializer instantiates a
8//! per-operator [`SubqueryExecutor`] from those specs.
9//!
10//! Execution model:
11//! - Every operator instance owns exactly one [`SubqueryExecutor`]; parallel
12//! partitions never share mutable runner state.
13//! - A runner materializes its sub-plan **once** on first use and re-runs it
14//! per row via the reset protocol (`StreamingExecutor::reset`), never
15//! rebuilding the pipeline.
16//! - Correlated runners receive the current row as a private correlation
17//! frame (`StreamingExecutor::inject_correlation_frame`); the frame is
18//! injected into the sub-plan's `Argument` source slot.
19//! - Non-correlated runners evaluate once and cache the result (EXISTS →
20//! bool, IN → `HashSet<Value>` with NULLs removed).
21//!
22//! NULL semantics: a NULL left operand or NULL result values never
23//! match, consistent with the conjunctive `keys_match` path.
24
25mod env;
26mod executor;
27mod runner;
28
29#[cfg(test)]
30mod tests;
31
32pub use env::EvalEnv;
33pub use executor::SubqueryExecutor;
34pub use runner::{GroupJoinSpec, SubqueryRunner, SubqueryRunnerSpec};