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)
}
}
}