mod join;
use anyhow::{anyhow, Result};
pub use join::Join;
mod select;
pub use select::Select;
mod filter;
pub use filter::Filter;
mod rangescan;
pub use rangescan::RangeScan;
mod delete;
pub use delete::Delete;
mod update;
pub use update::Update;
use crate::eval::Context;
use crate::Db;
#[derive(Debug)]
pub enum PlanNode {
None,
RangeScan(RangeScan),
Join(Join),
Filter(Filter),
Select(Select),
Delete(Delete),
Update(Update),
}
pub fn execute_plan_next<'a>(
plan: &mut PlanNode,
db: &mut Db,
ctx: Context,
) -> Result<Option<Context>> {
match plan {
PlanNode::None => Ok(None),
PlanNode::RangeScan(range_scan) => range_scan.execute(db, ctx),
PlanNode::Join(join) => join.execute(db, ctx),
PlanNode::Filter(filter) => {
let Some(ctx) = execute_plan_next(&mut filter.child, db, ctx)? else {
return Ok(None);
};
if ctx
.eval(&filter.cond)?
.into_bool()
.ok_or(anyhow!("filter expression does not evaluate to a BOOLEAN"))?
{
Ok(Some(ctx))
} else {
execute_plan_next(plan, db, ctx)
}
}
PlanNode::Select(select) => select.execute(db, ctx),
PlanNode::Delete(delete) => delete.execute(db, ctx),
PlanNode::Update(update) => update.execute(db, ctx),
}
}