Trait datafusion_expr::WindowUDFImpl

source ·
pub trait WindowUDFImpl:
    Debug
    + Send
    + Sync {
    // Required methods
    fn as_any(&self) -> &dyn Any;
    fn name(&self) -> &str;
    fn signature(&self) -> &Signature;
    fn return_type(&self, arg_types: &[DataType]) -> Result<DataType>;
    fn partition_evaluator(&self) -> Result<Box<dyn PartitionEvaluator>>;

    // Provided methods
    fn aliases(&self) -> &[String] { ... }
    fn simplify(&self) -> Option<WindowFunctionSimplification> { ... }
    fn equals(&self, other: &dyn WindowUDFImpl) -> bool { ... }
    fn hash_value(&self) -> u64 { ... }
    fn nullable(&self) -> bool { ... }
    fn sort_options(&self) -> Option<SortOptions> { ... }
    fn coerce_types(&self, _arg_types: &[DataType]) -> Result<Vec<DataType>> { ... }
}
Expand description

Trait for implementing WindowUDF.

This trait exposes the full API for implementing user defined window functions and can be used to implement any function.

See advanced_udwf.rs for a full example with complete implementation and WindowUDF for other available options.

§Basic Example

#[derive(Debug, Clone)]
struct SmoothIt {
  signature: Signature
}

impl SmoothIt {
  fn new() -> Self {
    Self {
      signature: Signature::uniform(1, vec![DataType::Int32], Volatility::Immutable)
     }
  }
}

/// Implement the WindowUDFImpl trait for AddOne
impl WindowUDFImpl for SmoothIt {
   fn as_any(&self) -> &dyn Any { self }
   fn name(&self) -> &str { "smooth_it" }
   fn signature(&self) -> &Signature { &self.signature }
   fn return_type(&self, args: &[DataType]) -> Result<DataType> {
     if !matches!(args.get(0), Some(&DataType::Int32)) {
       return plan_err!("smooth_it only accepts Int32 arguments");
     }
     Ok(DataType::Int32)
   }
   // The actual implementation would add one to the argument
   fn partition_evaluator(&self) -> Result<Box<dyn PartitionEvaluator>> { unimplemented!() }
}

// Create a new WindowUDF from the implementation
let smooth_it = WindowUDF::from(SmoothIt::new());

// Call the function `add_one(col)`
// smooth_it(speed) OVER (PARTITION BY car ORDER BY time ASC)
let expr = smooth_it.call(vec![col("speed")])
    .partition_by(vec![col("car")])
    .order_by(vec![col("time").sort(true, true)])
    .window_frame(WindowFrame::new(None))
    .build()
    .unwrap();

Required Methods§

source

fn as_any(&self) -> &dyn Any

Returns this object as an Any trait object

source

fn name(&self) -> &str

Returns this function’s name

source

fn signature(&self) -> &Signature

Returns the function’s Signature for information about what input types are accepted and the function’s Volatility.

source

fn return_type(&self, arg_types: &[DataType]) -> Result<DataType>

What DataType will be returned by this function, given the types of the arguments

source

fn partition_evaluator(&self) -> Result<Box<dyn PartitionEvaluator>>

Invoke the function, returning the PartitionEvaluator instance

Provided Methods§

source

fn aliases(&self) -> &[String]

Returns any aliases (alternate names) for this function.

Note: aliases should only include names other than Self::name. Defaults to [] (no aliases)

source

fn simplify(&self) -> Option<WindowFunctionSimplification>

Optionally apply per-UDWF simplification / rewrite rules.

This can be used to apply function specific simplification rules during optimization. The default implementation does nothing.

Note that DataFusion handles simplifying arguments and “constant folding” (replacing a function call with constant arguments such as my_add(1,2) --> 3 ). Thus, there is no need to implement such optimizations manually for specific UDFs.

Example: [simplify_udwf_expression.rs]: https://github.com/apache/arrow-datafusion/blob/main/datafusion-examples/examples/simplify_udwf_expression.rs

§Returns

None if simplify is not defined or,

Or, a closure with two arguments:

source

fn equals(&self, other: &dyn WindowUDFImpl) -> bool

Return true if this window UDF is equal to the other.

Allows customizing the equality of window UDFs. Must be consistent with Self::hash_value and follow the same rules as Eq:

  • reflexive: a.equals(a);
  • symmetric: a.equals(b) implies b.equals(a);
  • transitive: a.equals(b) and b.equals(c) implies a.equals(c).

By default, compares Self::name and Self::signature.

source

fn hash_value(&self) -> u64

Returns a hash value for this window UDF.

Allows customizing the hash code of window UDFs. Similarly to Hash and Eq, if Self::equals returns true for two UDFs, their hash_values must be the same.

By default, hashes Self::name and Self::signature.

source

fn nullable(&self) -> bool

Allows customizing nullable of column for this window UDF.

By default, the final result of evaluating the window UDF is allowed to have null values. But if that is not the case then it can be customized in the window UDF implementation.

source

fn sort_options(&self) -> Option<SortOptions>

Allows the window UDF to define a custom result ordering.

By default, a window UDF doesn’t introduce an ordering. But when specified by a window UDF this is used to update ordering equivalences.

source

fn coerce_types(&self, _arg_types: &[DataType]) -> Result<Vec<DataType>>

Coerce arguments of a function call to types that the function can evaluate.

This function is only called if WindowUDFImpl::signature returns crate::TypeSignature::UserDefined. Most UDWFs should return one of the other variants of TypeSignature which handle common cases

See the type coercion module documentation for more details on type coercion

For example, if your function requires a floating point arguments, but the user calls it like my_func(1::int) (aka with 1 as an integer), coerce_types could return [DataType::Float64] to ensure the argument was cast to 1::double

§Parameters
  • arg_types: The argument types of the arguments this function with
§Return value

A Vec the same length as arg_types. DataFusion will CAST the function call arguments to these specific types.

Trait Implementations§

source§

impl PartialEq for dyn WindowUDFImpl

source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for dyn WindowUDFImpl

source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more

Implementors§