quill_sql/expression/
aggregate.rs1use 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 pub func_kind: AggregateFunctionKind,
13 pub args: Vec<Expr>,
15 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}