datafusion_functions_aggregate/
any_value.rs1use std::fmt::Debug;
21use std::hash::Hash;
22use std::sync::Arc;
23
24use arrow::datatypes::{DataType, Field, FieldRef};
25use datafusion_common::{Result, not_impl_err};
26use datafusion_expr::function::{AccumulatorArgs, StateFieldsArgs};
27use datafusion_expr::utils::{AggregateOrderSensitivity, format_state_name};
28use datafusion_expr::{
29 Accumulator, AggregateUDFImpl, Documentation, Signature, Volatility,
30};
31use datafusion_macros::user_doc;
32
33use crate::first_last::TrivialFirstValueAccumulator;
34
35make_udaf_expr_and_func!(
36 AnyValue,
37 any_value,
38 expression,
39 "Returns an arbitrary non-null value",
40 any_value_udaf
41);
42
43#[user_doc(
44 doc_section(label = "General Functions"),
45 description = "Returns an arbitrary non-null value from a group, or NULL if the group contains only NULL values.",
46 syntax_example = "any_value(expression)",
47 sql_example = r#"```sql
48> SELECT any_value(column_name) FROM table_name;
49+------------------------+
50| any_value(column_name) |
51+------------------------+
52| arbitrary_value |
53+------------------------+
54```"#,
55 standard_argument(name = "expression",)
56)]
57#[derive(PartialEq, Eq, Hash, Debug)]
58pub struct AnyValue {
59 signature: Signature,
60}
61
62impl Default for AnyValue {
63 fn default() -> Self {
64 Self::new()
65 }
66}
67
68impl AnyValue {
69 pub fn new() -> Self {
70 Self {
71 signature: Signature::any(1, Volatility::Immutable),
72 }
73 }
74}
75
76impl AggregateUDFImpl for AnyValue {
77 fn name(&self) -> &str {
78 "any_value"
79 }
80
81 fn signature(&self) -> &Signature {
82 &self.signature
83 }
84
85 fn return_type(&self, _arg_types: &[DataType]) -> Result<DataType> {
86 not_impl_err!("Not called because return_field is implemented")
87 }
88
89 fn return_field(&self, arg_fields: &[FieldRef]) -> Result<FieldRef> {
90 Ok(Arc::new(
91 Field::new(self.name(), arg_fields[0].data_type().clone(), true)
92 .with_metadata(arg_fields[0].metadata().clone()),
93 ))
94 }
95
96 fn accumulator(&self, acc_args: AccumulatorArgs) -> Result<Box<dyn Accumulator>> {
97 TrivialFirstValueAccumulator::try_new(acc_args.return_field.data_type(), true)
98 .map(|acc| Box::new(acc) as _)
99 }
100
101 fn state_fields(&self, args: StateFieldsArgs) -> Result<Vec<FieldRef>> {
102 Ok(vec![
103 Field::new(
104 format_state_name(args.name, "any_value"),
105 args.return_type().clone(),
106 true,
107 )
108 .into(),
109 Field::new(
110 format_state_name(args.name, "any_value_is_set"),
111 DataType::Boolean,
112 true,
113 )
114 .into(),
115 ])
116 }
117
118 fn order_sensitivity(&self) -> AggregateOrderSensitivity {
119 AggregateOrderSensitivity::Insensitive
120 }
121
122 fn documentation(&self) -> Option<&Documentation> {
123 self.doc()
124 }
125}