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}