sochdb_query/executor/node.rs
1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3//! Volcano iterator model trait.
4
5use super::types::{Row, Schema};
6use sochdb_core::Result;
7
8/// Volcano-model plan node.
9///
10/// Each operator implements `next()` which returns one row at a time,
11/// pulling from child operators on demand. This enables streaming
12/// execution with predictable memory usage.
13///
14/// ```text
15/// while let Some(row) = node.next()? {
16/// // process row
17/// }
18/// ```
19pub trait PlanNode {
20 /// Schema of rows produced by this node.
21 fn schema(&self) -> &Schema;
22
23 /// Return the next row, or `None` when exhausted.
24 fn next(&mut self) -> Result<Option<Row>>;
25
26 /// Reset the operator for re-execution (e.g., inner side of nested loop join).
27 fn reset(&mut self) -> Result<()> {
28 Ok(()) // Default: no-op (many operators don't need reset)
29 }
30
31 /// Collect all remaining rows (convenience method).
32 fn collect_all(&mut self) -> Result<Vec<Row>> {
33 let mut rows = Vec::new();
34 while let Some(row) = self.next()? {
35 rows.push(row);
36 }
37 Ok(rows)
38 }
39}
40
41/// Blanket impl so `Box<dyn PlanNode>` itself implements `PlanNode`.
42impl PlanNode for Box<dyn PlanNode> {
43 fn schema(&self) -> &Schema {
44 (**self).schema()
45 }
46
47 fn next(&mut self) -> Result<Option<Row>> {
48 (**self).next()
49 }
50
51 fn reset(&mut self) -> Result<()> {
52 (**self).reset()
53 }
54}