1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
use super::{PostprocessingResult, PostprocessingStep};
use crate::base::{
    database::{OwnedColumn, OwnedTable},
    scalar::Scalar,
};
use indexmap::IndexMap;
use proof_of_sql_parser::{intermediate_ast::AliasedResultExpr, Identifier};
use serde::{Deserialize, Serialize};

/// The select expression used to select, reorder, and apply alias transformations
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SelectExpr {
    /// The aliased result expressions we select
    aliased_result_exprs: Vec<AliasedResultExpr>,
}

impl SelectExpr {
    /// Create a new `SelectExpr` node.
    pub fn new(aliased_result_exprs: Vec<AliasedResultExpr>) -> Self {
        Self {
            aliased_result_exprs,
        }
    }
}

impl<S: Scalar> PostprocessingStep<S> for SelectExpr {
    /// Apply the select transformation to the given `OwnedTable`.
    fn apply(&self, owned_table: OwnedTable<S>) -> PostprocessingResult<OwnedTable<S>> {
        let cols: IndexMap<Identifier, OwnedColumn<S>> = self
            .aliased_result_exprs
            .iter()
            .map(
                |aliased_result_expr| -> PostprocessingResult<(Identifier, OwnedColumn<S>)> {
                    let result_column = owned_table.evaluate(&aliased_result_expr.expr)?;
                    Ok((aliased_result_expr.alias, result_column))
                },
            )
            .collect::<PostprocessingResult<_>>()?;
        Ok(OwnedTable::try_new(cols)?)
    }
}