datafusion_functions_aggregate_common/
noop_accumulator.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use arrow::array::ArrayRef;
19use datafusion_common::{Result, ScalarValue};
20use datafusion_expr_common::accumulator::Accumulator;
21
22/// [`Accumulator`] that does no work and always returns a fixed value (default
23/// of `NULL` but can be customized).
24///
25/// Useful for aggregate functions that need to handle an input of [`DataType::Null`]
26/// that does no work.
27///
28/// [`DataType::Null`]: arrow::datatypes::DataType::Null
29#[derive(Debug)]
30pub struct NoopAccumulator {
31    evaluate_value: ScalarValue,
32}
33
34impl NoopAccumulator {
35    pub fn new(evaluate_value: ScalarValue) -> Self {
36        Self { evaluate_value }
37    }
38}
39
40impl Default for NoopAccumulator {
41    fn default() -> Self {
42        Self {
43            evaluate_value: ScalarValue::Null,
44        }
45    }
46}
47
48impl Accumulator for NoopAccumulator {
49    fn update_batch(&mut self, _values: &[ArrayRef]) -> Result<()> {
50        Ok(())
51    }
52
53    fn evaluate(&mut self) -> Result<ScalarValue> {
54        Ok(self.evaluate_value.clone())
55    }
56
57    fn size(&self) -> usize {
58        size_of_val(self)
59    }
60
61    fn state(&mut self) -> Result<Vec<ScalarValue>> {
62        // We ensure we return a state field even if unused otherwise we run into
63        // issues with queries like `SELECT agg_fn(NULL) FROM table`
64        Ok(vec![ScalarValue::Null])
65    }
66
67    fn merge_batch(&mut self, _states: &[ArrayRef]) -> Result<()> {
68        Ok(())
69    }
70}