sochdb_query/executor/
project.rs1use crate::sql::ast::Expr;
6use super::eval::eval_expr;
7use super::node::PlanNode;
8use super::types::{Row, Schema, ColumnMeta};
9use sochdb_core::Result;
10
11pub struct ProjectExpr {
13 pub expr: Expr,
14 pub alias: String,
15}
16
17pub struct ProjectNode {
24 input: Box<dyn PlanNode>,
25 exprs: Vec<ProjectExpr>,
26 output_schema: Schema,
27}
28
29impl ProjectNode {
30 pub fn new(input: Box<dyn PlanNode>, exprs: Vec<ProjectExpr>) -> Self {
31 let output_schema = Schema::new(
32 exprs.iter().map(|e| ColumnMeta::new(e.alias.clone())).collect(),
33 );
34 Self { input, exprs, output_schema }
35 }
36
37 pub fn columns(input: Box<dyn PlanNode>, columns: Vec<String>) -> Self {
39 let input_schema = input.schema().clone();
40 let exprs: Vec<ProjectExpr> = columns
41 .iter()
42 .map(|c| {
43 ProjectExpr {
44 expr: Expr::Column(crate::sql::ast::ColumnRef::new(c.clone())),
45 alias: c.clone(),
46 }
47 })
48 .collect();
49 let output_schema = Schema::new(
50 columns.iter().map(|c| {
51 input_schema
53 .columns
54 .iter()
55 .find(|cm| cm.name == *c)
56 .cloned()
57 .unwrap_or_else(|| ColumnMeta::new(c.clone()))
58 }).collect()
59 );
60 Self { input, exprs, output_schema }
61 }
62}
63
64impl PlanNode for ProjectNode {
65 fn schema(&self) -> &Schema {
66 &self.output_schema
67 }
68
69 fn next(&mut self) -> Result<Option<Row>> {
70 match self.input.next()? {
71 Some(row) => {
72 let input_schema = self.input.schema();
73 let mut output = Vec::with_capacity(self.exprs.len());
74 for pe in &self.exprs {
75 let val = eval_expr(&pe.expr, &row, input_schema)?;
76 output.push(val);
77 }
78 Ok(Some(output))
79 }
80 None => Ok(None),
81 }
82 }
83
84 fn reset(&mut self) -> Result<()> {
85 self.input.reset()
86 }
87}
88
89pub struct PassThroughNode {
91 input: Box<dyn PlanNode>,
92}
93
94impl PassThroughNode {
95 pub fn new(input: Box<dyn PlanNode>) -> Self {
96 Self { input }
97 }
98}
99
100impl PlanNode for PassThroughNode {
101 fn schema(&self) -> &Schema {
102 self.input.schema()
103 }
104
105 fn next(&mut self) -> Result<Option<Row>> {
106 self.input.next()
107 }
108
109 fn reset(&mut self) -> Result<()> {
110 self.input.reset()
111 }
112}