Skip to main content

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}