Skip to main content

quill_sql/function/aggregate/
avg.rs

1use crate::catalog::DataType;
2use crate::error::{QuillSQLError, QuillSQLResult};
3use crate::function::aggregate::Accumulator;
4use crate::utils::scalar::ScalarValue;
5
6#[derive(Debug, Clone)]
7pub struct AvgAccumulator {
8    sum: Option<f64>,
9    count: u64,
10}
11
12impl Default for AvgAccumulator {
13    fn default() -> Self {
14        Self::new()
15    }
16}
17
18impl AvgAccumulator {
19    pub fn new() -> Self {
20        Self {
21            sum: None,
22            count: 0,
23        }
24    }
25}
26
27impl Accumulator for AvgAccumulator {
28    fn update_value(&mut self, value: &ScalarValue) -> QuillSQLResult<()> {
29        if !value.is_null() {
30            let value = match value.cast_to(&DataType::Float64)? {
31                ScalarValue::Float64(Some(v)) => v,
32                _ => {
33                    return Err(QuillSQLError::Internal(format!(
34                        "Failed to cast value {} to float64",
35                        value
36                    )))
37                }
38            };
39
40            match self.sum {
41                Some(sum) => self.sum = Some(sum + value),
42                None => self.sum = Some(value),
43            }
44            self.count += 1;
45        }
46        Ok(())
47    }
48
49    fn evaluate(&self) -> QuillSQLResult<ScalarValue> {
50        Ok(ScalarValue::Float64(
51            self.sum.map(|f| f / self.count as f64),
52        ))
53    }
54}