quill_sql/expression/
column.rs

1use crate::catalog::Schema;
2use crate::catalog::{Column, DataType};
3use crate::error::QuillSQLResult;
4use crate::expression::ExprTrait;
5use crate::storage::tuple::Tuple;
6use crate::utils::scalar::ScalarValue;
7use crate::utils::table_ref::TableReference;
8
9/// A named reference to a qualified field in a schema.
10#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
11pub struct ColumnExpr {
12    /// relation/table reference.
13    pub relation: Option<TableReference>,
14    /// field/column name.
15    pub name: String,
16}
17
18impl ExprTrait for ColumnExpr {
19    fn data_type(&self, input_schema: &Schema) -> QuillSQLResult<DataType> {
20        let column = input_schema.column_with_name(self.relation.as_ref(), &self.name)?;
21        Ok(column.data_type)
22    }
23
24    fn nullable(&self, input_schema: &Schema) -> QuillSQLResult<bool> {
25        let column = input_schema.column_with_name(self.relation.as_ref(), &self.name)?;
26        Ok(column.nullable)
27    }
28
29    fn evaluate(&self, tuple: &Tuple) -> QuillSQLResult<ScalarValue> {
30        tuple
31            .value_by_name(self.relation.as_ref(), &self.name)
32            .cloned()
33    }
34
35    fn to_column(&self, input_schema: &Schema) -> QuillSQLResult<Column> {
36        let column = input_schema.column_with_name(self.relation.as_ref(), &self.name)?;
37        Ok(Column::new(
38            self.name.clone(),
39            self.data_type(input_schema)?,
40            self.nullable(input_schema)?,
41        )
42        .with_relation(self.relation.clone().or(column.relation.clone())))
43    }
44}
45
46impl std::fmt::Display for ColumnExpr {
47    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48        if let Some(relation) = self.relation.as_ref() {
49            write!(f, "{}.", relation)?;
50        }
51        write!(f, "{}", self.name)
52    }
53}