matdb 0.1.0

An experimental embedded SQL-like DBMS
Documentation
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()?)
    }
}