From 9c2366270c25de544d03c7c3e5d011ea3d50e133 Mon Sep 17 00:00:00 2001 From: Piotr Findeisen Date: Tue, 29 Oct 2024 21:22:00 +0100 Subject: [PATCH] Deprecate invoke and invoke_no_args in favor of invoke_batch `invoke_batch` covers all needs, so let's deprecate and eventually remove the redundant variants. --- datafusion/expr/src/udf.rs | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/datafusion/expr/src/udf.rs b/datafusion/expr/src/udf.rs index 83563603f2f3b..2e030911baabe 100644 --- a/datafusion/expr/src/udf.rs +++ b/datafusion/expr/src/udf.rs @@ -193,7 +193,9 @@ impl ScalarUDF { /// Invoke the function on `args`, returning the appropriate result. /// /// See [`ScalarUDFImpl::invoke`] for more details. + #[deprecated(since = "42.1.0", note = "Use `invoke_batch` instead")] pub fn invoke(&self, args: &[ColumnarValue]) -> Result { + #[allow(deprecated)] self.inner.invoke(args) } @@ -215,15 +217,18 @@ impl ScalarUDF { /// Invoke the function without `args` but number of rows, returning the appropriate result. /// /// See [`ScalarUDFImpl::invoke_no_args`] for more details. + #[deprecated(since = "42.1.0", note = "Use `invoke_batch` instead")] pub fn invoke_no_args(&self, number_rows: usize) -> Result { + #[allow(deprecated)] self.inner.invoke_no_args(number_rows) } /// Returns a `ScalarFunctionImplementation` that can invoke the function /// during execution - #[deprecated(since = "42.0.0", note = "Use `invoke` or `invoke_no_args` instead")] + #[deprecated(since = "42.0.0", note = "Use `invoke_batch` instead")] pub fn fun(&self) -> ScalarFunctionImplementation { let captured = Arc::clone(&self.inner); + #[allow(deprecated)] Arc::new(move |args| captured.invoke(args)) } @@ -478,6 +483,7 @@ pub trait ScalarUDFImpl: Debug + Send + Sync { /// to arrays, which will likely be simpler code, but be slower. /// /// [invoke_no_args]: ScalarUDFImpl::invoke_no_args + #[deprecated(since = "42.1.0", note = "Use `invoke_batch` instead")] fn invoke(&self, _args: &[ColumnarValue]) -> Result { not_impl_err!( "Function {} does not implement invoke but called", @@ -487,19 +493,40 @@ pub trait ScalarUDFImpl: Debug + Send + Sync { /// Invoke the function with `args` and the number of rows, /// returning the appropriate result. + /// + /// The function will be invoked with the slice of [`ColumnarValue`] + /// (either scalar or array). + /// + /// # Performance + /// + /// For the best performance, the implementations of `invoke` should handle + /// the common case when one or more of their arguments are constant values + /// (aka [`ColumnarValue::Scalar`]). + /// + /// [`ColumnarValue::values_to_arrays`] can be used to convert the arguments + /// to arrays, which will likely be simpler code, but be slower. fn invoke_batch( &self, args: &[ColumnarValue], number_rows: usize, ) -> Result { match args.is_empty() { - true => self.invoke_no_args(number_rows), - false => self.invoke(args), + true => + { + #[allow(deprecated)] + self.invoke_no_args(number_rows) + } + false => + { + #[allow(deprecated)] + self.invoke(args) + } } } /// Invoke the function without `args`, instead the number of rows are provided, /// returning the appropriate result. + #[deprecated(since = "42.1.0", note = "Use `invoke_batch` instead")] fn invoke_no_args(&self, _number_rows: usize) -> Result { not_impl_err!( "Function {} does not implement invoke_no_args but called", @@ -723,10 +750,12 @@ impl ScalarUDFImpl for AliasedScalarUDFImpl { } fn invoke(&self, args: &[ColumnarValue]) -> Result { + #[allow(deprecated)] self.inner.invoke(args) } fn invoke_no_args(&self, number_rows: usize) -> Result { + #[allow(deprecated)] self.inner.invoke_no_args(number_rows) }