diff --git a/datafusion/expr/src/udaf.rs b/datafusion/expr/src/udaf.rs index 3f4a99749cf6..af964b615445 100644 --- a/datafusion/expr/src/udaf.rs +++ b/datafusion/expr/src/udaf.rs @@ -249,6 +249,14 @@ impl AggregateUDF { pub fn simplify(&self) -> Option { self.inner.simplify() } + + /// Returns true if the function is max, false if the function is min + /// None in all other cases, used in certain optimizations or + /// or aggregate + /// + pub fn is_descending(&self) -> Option { + self.inner.is_descending() + } } impl From for AggregateUDF @@ -536,6 +544,16 @@ pub trait AggregateUDFImpl: Debug + Send + Sync { self.signature().hash(hasher); hasher.finish() } + + /// If this function is max, return true + /// if the function is min, return false + /// otherwise return None (the default) + /// + /// + /// Note: this is used to use special aggregate implementations in certain conditions + fn is_descending(&self) -> Option { + None + } } pub enum ReversedUDAF { diff --git a/datafusion/physical-expr-common/src/aggregate/mod.rs b/datafusion/physical-expr-common/src/aggregate/mod.rs index 4eede6567504..aa7273648c63 100644 --- a/datafusion/physical-expr-common/src/aggregate/mod.rs +++ b/datafusion/physical-expr-common/src/aggregate/mod.rs @@ -730,6 +730,12 @@ impl AggregateExpr for AggregateFunctionExpr { } } } + + fn get_minmax_desc(&self) -> Option<(Field, bool)> { + self.fun + .is_descending() + .and_then(|flag| self.field().ok().map(|f| (f, flag))) + } } impl PartialEq for AggregateFunctionExpr {