matdb 0.1.0

An experimental embedded SQL-like DBMS
Documentation
use anyhow::Result;

use crate::{eval::Context, Db};

use super::{execute_plan_next, PlanNode};

#[derive(Debug)]
pub struct Join {
    pub left: Box<PlanNode>,
    pub right: Box<PlanNode>,

    saved_left_ctx: Option<Context>,
}

impl Join {
    pub fn new(left: PlanNode, right: PlanNode) -> Self {
        Self {
            left: Box::new(left),
            right: Box::new(right),

            saved_left_ctx: None,
        }
    }

    pub fn execute(&mut self, db: &mut Db, ctx: Context) -> Result<Option<Context>> {
        let Some(left_ctx) = self
            .saved_left_ctx
            .take()
            .map(|x| Ok(x))
            .or_else(|| execute_plan_next(&mut self.left, db, ctx.clone()).transpose())
            .transpose()?
        else {
            return Ok(None);
        };

        self.saved_left_ctx = Some(left_ctx);

        if let Some(rows) =
            execute_plan_next(&mut self.right, db, self.saved_left_ctx.clone().unwrap())?
        {
            Ok(Some(rows))
        } else {
            self.saved_left_ctx = None;
            self.execute(db, ctx)
        }
    }
}