quill_sql/expression/
aggregate.rs

1use crate::catalog::{Column, DataType, Schema};
2use crate::error::{QuillSQLError, QuillSQLResult};
3use crate::expression::{Expr, ExprTrait};
4use crate::function::AggregateFunctionKind;
5use crate::storage::tuple::Tuple;
6use crate::utils::scalar::ScalarValue;
7use std::fmt::Debug;
8
9#[derive(Clone, PartialEq, Eq, Debug)]
10pub struct AggregateFunction {
11    /// the function kind
12    pub func_kind: AggregateFunctionKind,
13    /// List of expressions to feed to the functions as arguments
14    pub args: Vec<Expr>,
15    /// Whether this is a DISTINCT aggregation or not
16    pub distinct: bool,
17}
18
19impl ExprTrait for AggregateFunction {
20    fn data_type(&self, _input_schema: &Schema) -> QuillSQLResult<DataType> {
21        match self.func_kind {
22            AggregateFunctionKind::Count => Ok(DataType::Int64),
23            AggregateFunctionKind::Avg => Ok(DataType::Float64),
24        }
25    }
26
27    fn nullable(&self, _input_schema: &Schema) -> QuillSQLResult<bool> {
28        Ok(true)
29    }
30
31    fn evaluate(&self, tuple: &Tuple) -> QuillSQLResult<ScalarValue> {
32        match self.func_kind {
33            AggregateFunctionKind::Count | AggregateFunctionKind::Avg => {
34                let expr = self.args.first().ok_or(QuillSQLError::Internal(format!(
35                    "aggregate function {} should have one arg instead of {:?}",
36                    self.func_kind, self.args
37                )))?;
38                expr.evaluate(tuple)
39            }
40        }
41    }
42
43    fn to_column(&self, input_schema: &Schema) -> QuillSQLResult<Column> {
44        Ok(Column::new(
45            format!("{}", self),
46            self.data_type(input_schema)?,
47            self.nullable(input_schema)?,
48        ))
49    }
50}
51
52impl std::fmt::Display for AggregateFunction {
53    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54        write!(f, "{}", self.func_kind)
55    }
56}