## Coverage Report

#### Created: 2025-11-22 06:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /Users/andrewlamb/Software/datafusion/datafusion/physical-expr/src/aggregate.rs

    Line
    Count
    Source
    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
    18
    pub(crate) mod groups_accumulator {
    19
        #[allow(unused_imports)]
    20
        pub(crate) mod accumulate {
    21
            pub use datafusion_functions_aggregate_common::aggregate::groups_accumulator::accumulate::NullState;
    22
        }
    23
        pub use datafusion_functions_aggregate_common::aggregate::groups_accumulator::{
    24
            accumulate::NullState, GroupsAccumulatorAdapter,
    25
        };
    26
    }
    27
    pub(crate) mod stats {
    28
        pub use datafusion_functions_aggregate_common::stats::StatsType;
    29
    }
    30
    pub mod utils {
    31
        pub use datafusion_functions_aggregate_common::utils::{
    32
            get_accum_scalar_values_as_arrays, get_sort_options, ordering_fields,
    33
            DecimalAverager, Hashable,
    34
        };
    35
    }
    36
    37
    use std::fmt::Debug;
    38
    use std::sync::Arc;
    39
    40
    use crate::expressions::Column;
    41
    42
    use arrow::compute::SortOptions;
    43
    use arrow::datatypes::{DataType, FieldRef, Schema, SchemaRef};
    44
    use datafusion_common::{
    45
        assert_or_internal_err, internal_err, not_impl_err, DataFusionError, Result,
    46
        ScalarValue,
    47
    };
    48
    use datafusion_expr::{AggregateUDF, ReversedUDAF, SetMonotonicity};
    49
    use datafusion_expr_common::accumulator::Accumulator;
    50
    use datafusion_expr_common::groups_accumulator::GroupsAccumulator;
    51
    use datafusion_expr_common::type_coercion::aggregates::check_arg_count;
    52
    use datafusion_functions_aggregate_common::accumulator::{
    53
        AccumulatorArgs, StateFieldsArgs,
    54
    };
    55
    use datafusion_functions_aggregate_common::order::AggregateOrderSensitivity;
    56
    use datafusion_physical_expr_common::physical_expr::PhysicalExpr;
    57
    use datafusion_physical_expr_common::sort_expr::PhysicalSortExpr;
    58
    59
    /// Builder for physical [`AggregateFunctionExpr`]
    60
    ///
    61
    /// `AggregateFunctionExpr` contains the information necessary to call
    62
    /// an aggregate expression.
    63
    #[derive(Debug, Clone)]
    64
    pub struct AggregateExprBuilder {
    65
        fun: Arc<AggregateUDF>,
    66
        /// Physical expressions of the aggregate function
    67
        args: Vec<Arc<dyn PhysicalExpr>>,
    68
        alias: Option<String>,
    69
        /// A human readable name
    70
        human_display: String,
    71
        /// Arrow Schema for the aggregate function
    72
        schema: SchemaRef,
    73
        /// The physical order by expressions
    74
        order_bys: Vec<PhysicalSortExpr>,
    75
        /// Whether to ignore null values
    76
        ignore_nulls: bool,
    77
        /// Whether is distinct aggregate function
    78
        is_distinct: bool,
    79
        /// Whether the expression is reversed
    80
        is_reversed: bool,
    81
    }
    82
    83
    impl AggregateExprBuilder {
    84
    0
        pub fn new(fun: Arc<AggregateUDF>, args: Vec<Arc<dyn PhysicalExpr>>) -> Self {
    85
    0
            Self {
    86
    0
                fun,
    87
    0
                args,
    88
    0
                alias: None,
    89
    0
                human_display: String::default(),
    90
    0
                schema: Arc::new(Schema::empty()),
    91
    0
                order_bys: vec![],
    92
    0
                ignore_nulls: false,
    93
    0
                is_distinct: false,
    94
    0
                is_reversed: false,
    95
    0
            }
    96
    0
        }
    97
    98
        /// Constructs an `AggregateFunctionExpr` from the builder
    99
        ///
    100
        /// Note that an [`Self::alias`] must be provided before calling this method.
    101
        ///
    102
        /// # Example: Create an [`AggregateUDF`]
    103
        ///
    104
        /// In the following example, [`AggregateFunctionExpr`] will be built using [`AggregateExprBuilder`]
    105
        /// which provides a build function. Full example could be accessed from the source file.
    106
        ///
    107
        /// ```
    108
        /// # use std::any::Any;
    109
        /// # use std::sync::Arc;
    110
        /// # use arrow::datatypes::{DataType, FieldRef};
    111
        /// # use datafusion_common::{Result, ScalarValue};
    112
        /// # use datafusion_expr::{col, ColumnarValue, Documentation, Signature, Volatility, Expr};
    113
        /// # use datafusion_expr::{AggregateUDFImpl, AggregateUDF, Accumulator, function::{AccumulatorArgs, StateFieldsArgs}};
    114
        /// # use arrow::datatypes::Field;
    115
        /// #
    116
        /// # #[derive(Debug, Clone, PartialEq, Eq, Hash)]
    117
        /// # struct FirstValueUdf {
    118
        /// #     signature: Signature,
    119
        /// # }
    120
        /// #
    121
        /// # impl FirstValueUdf {
    122
        /// #     fn new() -> Self {
    123
        /// #         Self {
    124
        /// #             signature: Signature::any(1, Volatility::Immutable),
    125
        /// #         }
    126
        /// #     }
    127
        /// # }
    128
        /// #
    129
        /// # impl AggregateUDFImpl for FirstValueUdf {
    130
        /// #     fn as_any(&self) -> &dyn Any {
    131
        /// #         unimplemented!()
    132
        /// #     }
    133
        /// #
    134
        /// #     fn name(&self) -> &str {
    135
        /// #         unimplemented!()
    136
        /// #     }
    137
        /// #
    138
        /// #     fn signature(&self) -> &Signature {
    139
        /// #         unimplemented!()
    140
        /// #     }
    141
        /// #
    142
        /// #     fn return_type(&self, args: &[DataType]) -> Result<DataType> {
    143
        /// #         unimplemented!()
    144
        /// #     }
    145
        /// #
    146
        /// #     fn accumulator(&self, acc_args: AccumulatorArgs) -> Result<Box<dyn Accumulator>> {
    147
        /// #         unimplemented!()
    148
        /// #         }
    149
        /// #
    150
        /// #     fn state_fields(&self, args: StateFieldsArgs) -> Result<Vec<FieldRef>> {
    151
        /// #         unimplemented!()
    152
        /// #     }
    153
        /// #
    154
        /// #     fn documentation(&self) -> Option<&Documentation> {
    155
        /// #         unimplemented!()
    156
        /// #     }
    157
        /// # }
    158
        /// #
    159
        /// # let first_value = AggregateUDF::from(FirstValueUdf::new());
    160
        /// # let expr = first_value.call(vec![col("a")]);
    161
        /// #
    162
        /// # use datafusion_physical_expr::expressions::Column;
    163
        /// # use datafusion_physical_expr_common::physical_expr::PhysicalExpr;
    164
        /// # use datafusion_physical_expr::aggregate::AggregateExprBuilder;
    165
        /// # use datafusion_physical_expr::expressions::PhysicalSortExpr;
    166
        /// # use datafusion_physical_expr::PhysicalSortRequirement;
    167
        /// #
    168
        /// fn build_aggregate_expr() -> Result<()> {
    169
        ///     let args = vec![Arc::new(Column::new("a", 0)) as Arc<dyn PhysicalExpr>];
    170
        ///     let order_by = vec![PhysicalSortExpr {
    171
        ///         expr: Arc::new(Column::new("x", 1)) as Arc<dyn PhysicalExpr>,
    172
        ///         options: Default::default(),
    173
        ///     }];
    174
        ///
    175
        ///     let first_value = AggregateUDF::from(FirstValueUdf::new());
    176
        ///
    177
        ///     let aggregate_expr = AggregateExprBuilder::new(
    178
        ///         Arc::new(first_value),
    179
        ///         args
    180
        ///     )
    181
        ///     .order_by(order_by)
    182
        ///     .alias("first_a_by_x")
    183
        ///     .ignore_nulls()
    184
        ///     .build()?;
    185
        ///
    186
        ///     Ok(())
    187
        /// }
    188
        /// ```
    189
        ///
    190
        /// This creates a physical expression equivalent to SQL:
    191
        /// `first_value(a ORDER BY x) IGNORE NULLS AS first_a_by_x`
    192
    0
        pub fn build(self) -> Result<AggregateFunctionExpr> {
    193
            let Self {
    194
    0
                fun,
    195
    0
                args,
    196
    0
                alias,
    197
    0
                human_display,
    198
    0
                schema,
    199
    0
                order_bys,
    200
    0
                ignore_nulls,
    201
    0
                is_distinct,
    202
    0
                is_reversed,
    203
    0
            } = self;
    204
    0
            assert_or_internal_err!(!args.is_empty(), "args should not be empty");
    205
    206
    0
            let ordering_types = order_bys
    207
    0
                .iter()
    208
    0
                .map(|e| e.expr.data_type(&schema))
    209
    0
                .collect::<Result<Vec<_>>>()?;
    210
    211
    0
            let ordering_fields = utils::ordering_fields(&order_bys, &ordering_types);
    212
    213
    0
            let input_exprs_fields = args
    214
    0
                .iter()
    215
    0
                .map(|arg| arg.return_field(&schema))
    216
    0
                .collect::<Result<Vec<_>>>()?;
    217
    218
    0
            check_arg_count(
    219
    0
                fun.name(),
    220
    0
                &input_exprs_fields,
    221
    0
                &fun.signature().type_signature,
    222
    0
            )?;
    223
    224
    0
            let return_field = fun.return_field(&input_exprs_fields)?;
    225
    0
            let is_nullable = fun.is_nullable();
    226
    0
            let name = match alias {
    227
                None => {
    228
    0
                    return internal_err!(
    229
    0
                        "AggregateExprBuilder::alias must be provided prior to calling build"
    230
                    )
    231
                }
    232
    0
                Some(alias) => alias,
    233
            };
    234
    235
    0
            let arg_fields = args
    236
    0
                .iter()
    237
    0
                .map(|e| e.return_field(schema.as_ref()))
    238
    0
                .collect::<Result<Vec<_>>>()?;
    239
    240
    0
            Ok(AggregateFunctionExpr {
    241
    0
                fun: Arc::unwrap_or_clone(fun),
    242
    0
                args,
    243
    0
                arg_fields,
    244
    0
                return_field,
    245
    0
                name,
    246
    0
                human_display,
    247
    0
                schema: Arc::unwrap_or_clone(schema),
    248
    0
                order_bys,
    249
    0
                ignore_nulls,
    250
    0
                ordering_fields,
    251
    0
                is_distinct,
    252
    0
                input_fields: input_exprs_fields,
    253
    0
                is_reversed,
    254
    0
                is_nullable,
    255
    0
            })
    256
    0
        }
    257
    258
    0
        pub fn alias(mut self, alias: impl Into<String>) -> Self {
    259
    0
            self.alias = Some(alias.into());
    260
    0
            self
    261
    0
        }
    262
    263
    0
        pub fn human_display(mut self, name: String) -> Self {
    264
    0
            self.human_display = name;
    265
    0
            self
    266
    0
        }
    267
    268
    0
        pub fn schema(mut self, schema: SchemaRef) -> Self {
    269
    0
            self.schema = schema;
    270
    0
            self
    271
    0
        }
    272
    273
    0
        pub fn order_by(mut self, order_bys: Vec<PhysicalSortExpr>) -> Self {
    274
    0
            self.order_bys = order_bys;
    275
    0
            self
    276
    0
        }
    277
    278
    0
        pub fn reversed(mut self) -> Self {
    279
    0
            self.is_reversed = true;
    280
    0
            self
    281
    0
        }
    282
    283
    0
        pub fn with_reversed(mut self, is_reversed: bool) -> Self {
    284
    0
            self.is_reversed = is_reversed;
    285
    0
            self
    286
    0
        }
    287
    288
    0
        pub fn distinct(mut self) -> Self {
    289
    0
            self.is_distinct = true;
    290
    0
            self
    291
    0
        }
    292
    293
    0
        pub fn with_distinct(mut self, is_distinct: bool) -> Self {
    294
    0
            self.is_distinct = is_distinct;
    295
    0
            self
    296
    0
        }
    297
    298
    0
        pub fn ignore_nulls(mut self) -> Self {
    299
    0
            self.ignore_nulls = true;
    300
    0
            self
    301
    0
        }
    302
    303
    0
        pub fn with_ignore_nulls(mut self, ignore_nulls: bool) -> Self {
    304
    0
            self.ignore_nulls = ignore_nulls;
    305
    0
            self
    306
    0
        }
    307
    }
    308
    309
    /// Physical aggregate expression of a UDAF.
    310
    ///
    311
    /// Instances are constructed via [`AggregateExprBuilder`].
    312
    #[derive(Debug, Clone)]
    313
    pub struct AggregateFunctionExpr {
    314
        fun: AggregateUDF,
    315
        args: Vec<Arc<dyn PhysicalExpr>>,
    316
        /// Fields corresponding to args (same order & length)
    317
        arg_fields: Vec<FieldRef>,
    318
        /// Output / return field of this aggregate
    319
        return_field: FieldRef,
    320
        /// Output column name that this expression creates
    321
        name: String,
    322
        /// Simplified name for `tree` explain.
    323
        human_display: String,
    324
        schema: Schema,
    325
        // The physical order by expressions
    326
        order_bys: Vec<PhysicalSortExpr>,
    327
        // Whether to ignore null values
    328
        ignore_nulls: bool,
    329
        // fields used for order sensitive aggregation functions
    330
        ordering_fields: Vec<FieldRef>,
    331
        is_distinct: bool,
    332
        is_reversed: bool,
    333
        input_fields: Vec<FieldRef>,
    334
        is_nullable: bool,
    335
    }
    336
    337
    impl AggregateFunctionExpr {
    338
        /// Return the `AggregateUDF` used by this `AggregateFunctionExpr`
    339
    0
        pub fn fun(&self) -> &AggregateUDF {
    340
    0
            &self.fun
    341
    0
        }
    342
    343
        /// expressions that are passed to the Accumulator.
    344
        /// Single-column aggregations such as `sum` return a single value, others (e.g. `cov`) return many.
    345
    0
        pub fn expressions(&self) -> Vec<Arc<dyn PhysicalExpr>> {
    346
    0
            self.args.clone()
    347
    0
        }
    348
    349
        /// Human readable name such as `"MIN(c2)"`.
    350
    0
        pub fn name(&self) -> &str {
    351
    0
            &self.name
    352
    0
        }
    353
    354
        /// Simplified name for `tree` explain.
    355
    0
        pub fn human_display(&self) -> &str {
    356
    0
            &self.human_display
    357
    0
        }
    358
    359
        /// Return if the aggregation is distinct
    360
    0
        pub fn is_distinct(&self) -> bool {
    361
    0
            self.is_distinct
    362
    0
        }
    363
    364
        /// Return if the aggregation ignores nulls
    365
    0
        pub fn ignore_nulls(&self) -> bool {
    366
    0
            self.ignore_nulls
    367
    0
        }
    368
    369
        /// Return if the aggregation is reversed
    370
    0
        pub fn is_reversed(&self) -> bool {
    371
    0
            self.is_reversed
    372
    0
        }
    373
    374
        /// Return if the aggregation is nullable
    375
    0
        pub fn is_nullable(&self) -> bool {
    376
    0
            self.is_nullable
    377
    0
        }
    378
    379
        /// the field of the final result of this aggregation.
    380
    0
        pub fn field(&self) -> FieldRef {
    381
    0
            self.return_field
    382
    0
                .as_ref()
    383
    0
                .clone()
    384
    0
                .with_name(&self.name)
    385
    0
                .into()
    386
    0
        }
    387
    388
        /// the accumulator used to accumulate values from the expressions.
    389
        /// the accumulator expects the same number of arguments as `expressions` and must
    390
        /// return states with the same description as `state_fields`
    391
    0
        pub fn create_accumulator(&self) -> Result<Box<dyn Accumulator>> {
    392
    0
            let acc_args = AccumulatorArgs {
    393
    0
                return_field: Arc::clone(&self.return_field),
    394
    0
                schema: &self.schema,
    395
    0
                expr_fields: &self.arg_fields,
    396
    0
                ignore_nulls: self.ignore_nulls,
    397
    0
                order_bys: self.order_bys.as_ref(),
    398
    0
                is_distinct: self.is_distinct,
    399
    0
                name: &self.name,
    400
    0
                is_reversed: self.is_reversed,
    401
    0
                exprs: &self.args,
    402
    0
            };
    403
    404
    0
            self.fun.accumulator(acc_args)
    405
    0
        }
    406
    407
        /// the field of the final result of this aggregation.
    408
    0
        pub fn state_fields(&self) -> Result<Vec<FieldRef>> {
    409
    0
            let args = StateFieldsArgs {
    410
    0
                name: &self.name,
    411
    0
                input_fields: &self.input_fields,
    412
    0
                return_field: Arc::clone(&self.return_field),
    413
    0
                ordering_fields: &self.ordering_fields,
    414
    0
                is_distinct: self.is_distinct,
    415
    0
            };
    416
    417
    0
            self.fun.state_fields(args)
    418
    0
        }
    419
    420
        /// Returns the ORDER BY expressions for the aggregate function.
    421
    0
        pub fn order_bys(&self) -> &[PhysicalSortExpr] {
    422
    0
            if self.order_sensitivity().is_insensitive() {
    423
    0
                &[]
    424
            } else {
    425
    0
                &self.order_bys
    426
            }
    427
    0
        }
    428
    429
        /// Indicates whether aggregator can produce the correct result with any
    430
        /// arbitrary input ordering. By default, we assume that aggregate expressions
    431
        /// are order insensitive.
    432
    0
        pub fn order_sensitivity(&self) -> AggregateOrderSensitivity {
    433
    0
            if self.order_bys.is_empty() {
    434
    0
                AggregateOrderSensitivity::Insensitive
    435
            } else {
    436
                // If there is an ORDER BY clause, use the sensitivity of the implementation:
    437
    0
                self.fun.order_sensitivity()
    438
            }
    439
    0
        }
    440
    441
        /// Sets the indicator whether ordering requirements of the aggregator is
    442
        /// satisfied by its input. If this is not the case, aggregators with order
    443
        /// sensitivity `AggregateOrderSensitivity::Beneficial` can still produce
    444
        /// the correct result with possibly more work internally.
    445
        ///
    446
        /// # Returns
    447
        ///
    448
        /// Returns `Ok(Some(updated_expr))` if the process completes successfully.
    449
        /// If the expression can benefit from existing input ordering, but does
    450
        /// not implement the method, returns an error. Order insensitive and hard
    451
        /// requirement aggregators return `Ok(None)`.
    452
    0
        pub fn with_beneficial_ordering(
    453
    0
            self: Arc<Self>,
    454
    0
            beneficial_ordering: bool,
    455
    0
        ) -> Result<Option<AggregateFunctionExpr>> {
    456
    0
            let Some(updated_fn) = self
    457
    0
                .fun
    458
    0
                .clone()
    459
    0
                .with_beneficial_ordering(beneficial_ordering)?
    460
            else {
    461
    0
                return Ok(None);
    462
            };
    463
    464
    0
            AggregateExprBuilder::new(Arc::new(updated_fn), self.args.to_vec())
    465
    0
                .order_by(self.order_bys.clone())
    466
    0
                .schema(Arc::new(self.schema.clone()))
    467
    0
                .alias(self.name().to_string())
    468
    0
                .with_ignore_nulls(self.ignore_nulls)
    469
    0
                .with_distinct(self.is_distinct)
    470
    0
                .with_reversed(self.is_reversed)
    471
    0
                .build()
    472
    0
                .map(Some)
    473
    0
        }
    474
    475
        /// Creates accumulator implementation that supports retract
    476
    0
        pub fn create_sliding_accumulator(&self) -> Result<Box<dyn Accumulator>> {
    477
    0
            let args = AccumulatorArgs {
    478
    0
                return_field: Arc::clone(&self.return_field),
    479
    0
                schema: &self.schema,
    480
    0
                expr_fields: &self.arg_fields,
    481
    0
                ignore_nulls: self.ignore_nulls,
    482
    0
                order_bys: self.order_bys.as_ref(),
    483
    0
                is_distinct: self.is_distinct,
    484
    0
                name: &self.name,
    485
    0
                is_reversed: self.is_reversed,
    486
    0
                exprs: &self.args,
    487
    0
            };
    488
    489
    0
            let accumulator = self.fun.create_sliding_accumulator(args)?;
    490
    491
            // Accumulators that have window frame startings different
    492
            // than `UNBOUNDED PRECEDING`, such as `1 PRECEDING`, need to
    493
            // implement retract_batch method in order to run correctly
    494
            // currently in DataFusion.
    495
            //
    496
            // If this `retract_batches` is not present, there is no way
    497
            // to calculate result correctly. For example, the query
    498
            //
    499
            // ```sql
    500
            // SELECT
    501
            //  SUM(a) OVER(ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS sum_a
    502
            // FROM
    503
            //  t
    504
            // ```
    505
            //
    506
            // 1. First sum value will be the sum of rows between `[0, 1)`,
    507
            //
    508
            // 2. Second sum value will be the sum of rows between `[0, 2)`
    509
            //
    510
            // 3. Third sum value will be the sum of rows between `[1, 3)`, etc.
    511
            //
    512
            // Since the accumulator keeps the running sum:
    513
            //
    514
            // 1. First sum we add to the state sum value between `[0, 1)`
    515
            //
    516
            // 2. Second sum we add to the state sum value between `[1, 2)`
    517
            // (`[0, 1)` is already in the state sum, hence running sum will
    518
            // cover `[0, 2)` range)
    519
            //
    520
            // 3. Third sum we add to the state sum value between `[2, 3)`
    521
            // (`[0, 2)` is already in the state sum).  Also we need to
    522
            // retract values between `[0, 1)` by this way we can obtain sum
    523
            // between [1, 3) which is indeed the appropriate range.
    524
            //
    525
            // When we use `UNBOUNDED PRECEDING` in the query starting
    526
            // index will always be 0 for the desired range, and hence the
    527
            // `retract_batch` method will not be called. In this case
    528
            // having retract_batch is not a requirement.
    529
            //
    530
            // This approach is a a bit different than window function
    531
            // approach. In window function (when they use a window frame)
    532
            // they get all the desired range during evaluation.
    533
    0
            if !accumulator.supports_retract_batch() {
    534
    0
                return not_impl_err!(
    535
    0
                    "Aggregate can not be used as a sliding accumulator because \
    536
    0
                         `retract_batch` is not implemented: {}",
    537
                    self.name
    538
                );
    539
    0
            }
    540
    0
            Ok(accumulator)
    541
    0
        }
    542
    543
        /// If the aggregate expression has a specialized
    544
        /// [`GroupsAccumulator`] implementation. If this returns true,
    545
        /// `[Self::create_groups_accumulator`] will be called.
    546
    0
        pub fn groups_accumulator_supported(&self) -> bool {
    547
    0
            let args = AccumulatorArgs {
    548
    0
                return_field: Arc::clone(&self.return_field),
    549
    0
                schema: &self.schema,
    550
    0
                expr_fields: &self.arg_fields,
    551
    0
                ignore_nulls: self.ignore_nulls,
    552
    0
                order_bys: self.order_bys.as_ref(),
    553
    0
                is_distinct: self.is_distinct,
    554
    0
                name: &self.name,
    555
    0
                is_reversed: self.is_reversed,
    556
    0
                exprs: &self.args,
    557
    0
            };
    558
    0
            self.fun.groups_accumulator_supported(args)
    559
    0
        }
    560
    561
        /// Return a specialized [`GroupsAccumulator`] that manages state
    562
        /// for all groups.
    563
        ///
    564
        /// For maximum performance, a [`GroupsAccumulator`] should be
    565
        /// implemented in addition to [`Accumulator`].
    566
    0
        pub fn create_groups_accumulator(&self) -> Result<Box<dyn GroupsAccumulator>> {
    567
    0
            let args = AccumulatorArgs {
    568
    0
                return_field: Arc::clone(&self.return_field),
    569
    0
                schema: &self.schema,
    570
    0
                expr_fields: &self.arg_fields,
    571
    0
                ignore_nulls: self.ignore_nulls,
    572
    0
                order_bys: self.order_bys.as_ref(),
    573
    0
                is_distinct: self.is_distinct,
    574
    0
                name: &self.name,
    575
    0
                is_reversed: self.is_reversed,
    576
    0
                exprs: &self.args,
    577
    0
            };
    578
    0
            self.fun.create_groups_accumulator(args)
    579
    0
        }
    580
    581
        /// Construct an expression that calculates the aggregate in reverse.
    582
        /// Typically the "reverse" expression is itself (e.g. SUM, COUNT).
    583
        /// For aggregates that do not support calculation in reverse,
    584
        /// returns None (which is the default value).
    585
    0
        pub fn reverse_expr(&self) -> Option<AggregateFunctionExpr> {
    586
    0
            match self.fun.reverse_udf() {
    587
    0
                ReversedUDAF::NotSupported => None,
    588
    0
                ReversedUDAF::Identical => Some(self.clone()),
    589
    0
                ReversedUDAF::Reversed(reverse_udf) => {
    590
    0
                    let mut name = self.name().to_string();
    591
                    // If the function is changed, we need to reverse order_by clause as well
    592
                    // i.e. First(a order by b asc null first) -> Last(a order by b desc null last)
    593
    0
                    if self.fun().name() != reverse_udf.name() {
    594
    0
                        replace_order_by_clause(&mut name);
    595
    0
                    }
    596
    0
                    replace_fn_name_clause(&mut name, self.fun.name(), reverse_udf.name());
    597
    598
    0
                    AggregateExprBuilder::new(reverse_udf, self.args.to_vec())
    599
    0
                        .order_by(self.order_bys.iter().map(|e| e.reverse()).collect())
    600
    0
                        .schema(Arc::new(self.schema.clone()))
    601
    0
                        .alias(name)
    602
    0
                        .with_ignore_nulls(self.ignore_nulls)
    603
    0
                        .with_distinct(self.is_distinct)
    604
    0
                        .with_reversed(!self.is_reversed)
    605
    0
                        .build()
    606
    0
                        .ok()
    607
                }
    608
            }
    609
    0
        }
    610
    611
        /// Returns all expressions used in the [`AggregateFunctionExpr`].
    612
        /// These expressions are  (1)function arguments, (2) order by expressions.
    613
    0
        pub fn all_expressions(&self) -> AggregatePhysicalExpressions {
    614
    0
            let args = self.expressions();
    615
    0
            let order_by_exprs = self
    616
    0
                .order_bys()
    617
    0
                .iter()
    618
    0
                .map(|sort_expr| Arc::clone(&sort_expr.expr))
    619
    0
                .collect();
    620
    0
            AggregatePhysicalExpressions {
    621
    0
                args,
    622
    0
                order_by_exprs,
    623
    0
            }
    624
    0
        }
    625
    626
        /// Rewrites [`AggregateFunctionExpr`], with new expressions given. The argument should be consistent
    627
        /// with the return value of the [`AggregateFunctionExpr::all_expressions`] method.
    628
        /// Returns `Some(Arc<dyn AggregateExpr>)` if re-write is supported, otherwise returns `None`.
    629
    0
        pub fn with_new_expressions(
    630
    0
            &self,
    631
    0
            args: Vec<Arc<dyn PhysicalExpr>>,
    632
    0
            order_by_exprs: Vec<Arc<dyn PhysicalExpr>>,
    633
    0
        ) -> Option<AggregateFunctionExpr> {
    634
    0
            if args.len() != self.args.len()
    635
    0
                || (self.order_sensitivity() != AggregateOrderSensitivity::Insensitive
    636
    0
                    && order_by_exprs.len() != self.order_bys.len())
    637
            {
    638
    0
                return None;
    639
    0
            }
    640
    641
    0
            let new_order_bys = self
    642
    0
                .order_bys
    643
    0
                .iter()
    644
    0
                .zip(order_by_exprs)
    645
    0
                .map(|(req, new_expr)| PhysicalSortExpr {
    646
    0
                    expr: new_expr,
    647
    0
                    options: req.options,
    648
    0
                })
    649
    0
                .collect();
    650
    651
    0
            Some(AggregateFunctionExpr {
    652
    0
                fun: self.fun.clone(),
    653
    0
                args,
    654
    0
                // TODO: need to align arg_fields here with new args
    655
    0
                //       https://github.com/apache/datafusion/issues/18149
    656
    0
                arg_fields: self.arg_fields.clone(),
    657
    0
                return_field: Arc::clone(&self.return_field),
    658
    0
                name: self.name.clone(),
    659
    0
                // TODO: Human name should be updated after re-write to not mislead
    660
    0
                human_display: self.human_display.clone(),
    661
    0
                schema: self.schema.clone(),
    662
    0
                order_bys: new_order_bys,
    663
    0
                ignore_nulls: self.ignore_nulls,
    664
    0
                ordering_fields: self.ordering_fields.clone(),
    665
    0
                is_distinct: self.is_distinct,
    666
    0
                is_reversed: false,
    667
    0
                input_fields: self.input_fields.clone(),
    668
    0
                is_nullable: self.is_nullable,
    669
    0
            })
    670
    0
        }
    671
    672
        /// If this function is max, return (output_field, true)
    673
        /// if the function is min, return (output_field, false)
    674
        /// otherwise return None (the default)
    675
        ///
    676
        /// output_field is the name of the column produced by this aggregate
    677
        ///
    678
        /// Note: this is used to use special aggregate implementations in certain conditions
    679
    0
        pub fn get_minmax_desc(&self) -> Option<(FieldRef, bool)> {
    680
    0
            self.fun.is_descending().map(|flag| (self.field(), flag))
    681
    0
        }
    682
    683
        /// Returns default value of the function given the input is Null
    684
        /// Most of the aggregate function return Null if input is Null,
    685
        /// while `count` returns 0 if input is Null
    686
    0
        pub fn default_value(&self, data_type: &DataType) -> Result<ScalarValue> {
    687
    0
            self.fun.default_value(data_type)
    688
    0
        }
    689
    690
        /// Indicates whether the aggregation function is monotonic as a set
    691
        /// function. See [`SetMonotonicity`] for details.
    692
    0
        pub fn set_monotonicity(&self) -> SetMonotonicity {
    693
    0
            let field = self.field();
    694
    0
            let data_type = field.data_type();
    695
    0
            self.fun.inner().set_monotonicity(data_type)
    696
    0
        }
    697
    698
        /// Returns `PhysicalSortExpr` based on the set monotonicity of the function.
    699
    0
        pub fn get_result_ordering(&self, aggr_func_idx: usize) -> Option<PhysicalSortExpr> {
    700
            // If the aggregate expressions are set-monotonic, the output data is
    701
            // naturally ordered with it per group or partition.
    702
    0
            let monotonicity = self.set_monotonicity();
    703
    0
            if monotonicity == SetMonotonicity::NotMonotonic {
    704
    0
                return None;
    705
    0
            }
    706
    0
            let expr = Arc::new(Column::new(self.name(), aggr_func_idx));
    707
    0
            let options =
    708
    0
                SortOptions::new(monotonicity == SetMonotonicity::Decreasing, false);
    709
    0
            Some(PhysicalSortExpr { expr, options })
    710
    0
        }
    711
    }
    712
    713
    /// Stores the physical expressions used inside the `AggregateExpr`.
    714
    pub struct AggregatePhysicalExpressions {
    715
        /// Aggregate function arguments
    716
        pub args: Vec<Arc<dyn PhysicalExpr>>,
    717
        /// Order by expressions
    718
        pub order_by_exprs: Vec<Arc<dyn PhysicalExpr>>,
    719
    }
    720
    721
    impl PartialEq for AggregateFunctionExpr {
    722
    0
        fn eq(&self, other: &Self) -> bool {
    723
    0
            self.name == other.name
    724
    0
                && self.return_field == other.return_field
    725
    0
                && self.fun == other.fun
    726
    0
                && self.args.len() == other.args.len()
    727
    0
                && self
    728
    0
                    .args
    729
    0
                    .iter()
    730
    0
                    .zip(other.args.iter())
    731
    0
                    .all(|(this_arg, other_arg)| this_arg.eq(other_arg))
    732
    0
        }
    733
    }
    734
    735
    0
    fn replace_order_by_clause(order_by: &mut String) {
    736
    0
        let suffixes = [
    737
    0
            (" DESC NULLS FIRST]", " ASC NULLS LAST]"),
    738
    0
            (" ASC NULLS FIRST]", " DESC NULLS LAST]"),
    739
    0
            (" DESC NULLS LAST]", " ASC NULLS FIRST]"),
    740
    0
            (" ASC NULLS LAST]", " DESC NULLS FIRST]"),
    741
    0
        ];
    742
    743
    0
        if let Some(start) = order_by.find("ORDER BY [") {
    744
    0
            if let Some(end) = order_by[start..].find(']') {
    745
    0
                let order_by_start = start + 9;
    746
    0
                let order_by_end = start + end;
    747
    748
    0
                let column_order = &order_by[order_by_start..=order_by_end];
    749
    0
                for (suffix, replacement) in suffixes {
    750
    0
                    if column_order.ends_with(suffix) {
    751
    0
                        let new_order = column_order.replace(suffix, replacement);
    752
    0
                        order_by.replace_range(order_by_start..=order_by_end, &new_order);
    753
    0
                        break;
    754
    0
                    }
    755
                }
    756
    0
            }
    757
    0
        }
    758
    0
    }
    759
    760
    0
    fn replace_fn_name_clause(aggr_name: &mut String, fn_name_old: &str, fn_name_new: &str) {
    761
    0
        *aggr_name = aggr_name.replace(fn_name_old, fn_name_new);
    762
    0
    }