use anyhow::Result;
use crate::{
ast::{Column, Expr},
eval::Context,
Db,
};
use super::{execute_plan_next, PlanNode};
#[derive(Debug)]
pub struct Select {
child: Box<PlanNode>,
exprs: Vec<Expr>,
alias: String,
}
impl Select {
pub fn new(child: PlanNode, exprs: Vec<Expr>, alias: String) -> Self {
Self {
child: Box::new(child),
exprs,
alias,
}
}
pub fn headers(&self) -> Vec<String> {
self.exprs.iter().map(|e| format!("{e}")).collect()
}
pub fn execute(&mut self, db: &mut Db, ctx: Context) -> Result<Option<Context>> {
Ok(execute_plan_next(&mut self.child, db, ctx)?
.map(|mut old_ctx| -> Result<Context> {
let mut ctx = Context::new(Vec::new());
for (n, v) in self
.exprs
.iter()
.map(|e| Ok((e.to_string(), old_ctx.eval(e)?)))
.collect::<Result<Vec<_>>>()?
{
old_ctx.set(Column(self.alias.clone(), n.clone()), v.clone());
ctx.set(Column(self.alias.clone(), n), v);
}
Ok(ctx)
})
.transpose()?)
}
}