@@ -244,11 +244,13 @@ where
244244/// # use std::sync::LazyLock;
245245/// # use arrow::datatypes::{DataType, Field, FieldRef};
246246/// # use datafusion_common::{DataFusionError, plan_err, Result};
247- /// # use datafusion_expr::{col, Signature, Volatility, PartitionEvaluator, WindowFrame, ExprFunctionExt, Documentation};
247+ /// # use datafusion_expr::{col, Signature, Volatility, PartitionEvaluator, WindowFrame, ExprFunctionExt, Documentation, LimitEffect };
248248/// # use datafusion_expr::{WindowUDFImpl, WindowUDF};
249249/// # use datafusion_functions_window_common::field::WindowUDFFieldArgs;
250250/// # use datafusion_functions_window_common::partition::PartitionEvaluatorArgs;
251251/// # use datafusion_expr::window_doc_sections::DOC_SECTION_ANALYTICAL;
252+ /// # use datafusion_physical_expr_common::physical_expr;
253+ /// # use std::sync::Arc;
252254///
253255/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
254256/// struct SmoothIt {
@@ -295,6 +297,9 @@ where
295297/// fn documentation(&self) -> Option<&Documentation> {
296298/// Some(get_doc())
297299/// }
300+ /// fn limit_effect(&self, _args: &[Arc<dyn physical_expr::PhysicalExpr>]) -> LimitEffect {
301+ /// LimitEffect::Unknown
302+ /// }
298303/// }
299304///
300305/// // Create a new WindowUDF from the implementation
@@ -421,6 +426,23 @@ pub trait WindowUDFImpl: Debug + DynEq + DynHash + Send + Sync {
421426 fn documentation ( & self ) -> Option < & Documentation > {
422427 None
423428 }
429+
430+ /// If not causal, returns the effect this function will have on the window
431+ fn limit_effect ( & self , _args : & [ Arc < dyn PhysicalExpr > ] ) -> LimitEffect {
432+ LimitEffect :: Unknown
433+ }
434+ }
435+
436+ /// the effect this function will have on the limit pushdown
437+ pub enum LimitEffect {
438+ /// Does not affect the limit (i.e. this is causal)
439+ None ,
440+ /// Either undeclared, or dynamic (only evaluatable at run time)
441+ Unknown ,
442+ /// Grow the limit by N rows
443+ Relative ( usize ) ,
444+ /// Limit needs to be at least N rows
445+ Absolute ( usize ) ,
424446}
425447
426448pub enum ReversedUDWF {
@@ -530,19 +552,25 @@ impl WindowUDFImpl for AliasedWindowUDFImpl {
530552 fn documentation ( & self ) -> Option < & Documentation > {
531553 self . inner . documentation ( )
532554 }
555+
556+ fn limit_effect ( & self , args : & [ Arc < dyn PhysicalExpr > ] ) -> LimitEffect {
557+ self . inner . limit_effect ( args)
558+ }
533559}
534560
535561#[ cfg( test) ]
536562mod test {
537- use crate :: { PartitionEvaluator , WindowUDF , WindowUDFImpl } ;
563+ use crate :: { LimitEffect , PartitionEvaluator , WindowUDF , WindowUDFImpl } ;
538564 use arrow:: datatypes:: { DataType , FieldRef } ;
539565 use datafusion_common:: Result ;
540566 use datafusion_expr_common:: signature:: { Signature , Volatility } ;
541567 use datafusion_functions_window_common:: field:: WindowUDFFieldArgs ;
542568 use datafusion_functions_window_common:: partition:: PartitionEvaluatorArgs ;
569+ use datafusion_physical_expr_common:: physical_expr:: PhysicalExpr ;
543570 use std:: any:: Any ;
544571 use std:: cmp:: Ordering ;
545572 use std:: hash:: { DefaultHasher , Hash , Hasher } ;
573+ use std:: sync:: Arc ;
546574
547575 #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
548576 struct AWindowUDF {
@@ -581,6 +609,10 @@ mod test {
581609 fn field ( & self , _field_args : WindowUDFFieldArgs ) -> Result < FieldRef > {
582610 unimplemented ! ( )
583611 }
612+
613+ fn limit_effect ( & self , _args : & [ Arc < dyn PhysicalExpr > ] ) -> LimitEffect {
614+ LimitEffect :: Unknown
615+ }
584616 }
585617
586618 #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
@@ -620,6 +652,10 @@ mod test {
620652 fn field ( & self , _field_args : WindowUDFFieldArgs ) -> Result < FieldRef > {
621653 unimplemented ! ( )
622654 }
655+
656+ fn limit_effect ( & self , _args : & [ Arc < dyn PhysicalExpr > ] ) -> LimitEffect {
657+ LimitEffect :: Unknown
658+ }
623659 }
624660
625661 #[ test]
0 commit comments