From b84e11b0cb691b1d588d45f699800bcd1ad2dc11 Mon Sep 17 00:00:00 2001 From: Parman Mohammadalizadeh Date: Fri, 21 Aug 2026 09:24:41 +0200 Subject: [PATCH] chore: remove deprecated ScalarUDF / ScalarUDFImpl methods The API health policy keeps a deprecated API for 6 major versions or 6 months, whichever is longer. main is at 55.0.0, so anything deprecated in 50.0.0 or earlier can be removed. Removes ScalarUDFImpl::is_nullable (45.0.0), ScalarUDF::display_name, ScalarUDF::is_nullable and ScalarUDFImpl::display_name (all 50.0.0), along with the matching AliasedScalarUDFImpl delegates and the three display_name overrides on ArrayElement, ArraySlice and GetFieldFunc. Each of those three defines its own schema_name, which is what names output columns, so query output is unchanged. Part of #24535 --- datafusion/expr/src/udf.rs | 54 +--------------------- datafusion/functions-nested/src/extract.rs | 18 -------- datafusion/functions/src/core/getfield.rs | 20 -------- 3 files changed, 1 insertion(+), 91 deletions(-) diff --git a/datafusion/expr/src/udf.rs b/datafusion/expr/src/udf.rs index 2de3be4c10fa4..e6acea173cafc 100644 --- a/datafusion/expr/src/udf.rs +++ b/datafusion/expr/src/udf.rs @@ -28,7 +28,7 @@ use arrow::datatypes::{DataType, Field, FieldRef}; #[cfg(debug_assertions)] use datafusion_common::assert_or_internal_err; use datafusion_common::config::ConfigOptions; -use datafusion_common::{ExprSchema, Result, ScalarValue, not_impl_err}; +use datafusion_common::{Result, ScalarValue, not_impl_err}; use datafusion_expr_common::dyn_eq::{DynEq, DynHash}; use datafusion_expr_common::interval_arithmetic::Interval; use datafusion_expr_common::placement::ExpressionPlacement; @@ -183,18 +183,6 @@ impl ScalarUDF { self.inner.name() } - /// Returns this function's display_name. - /// - /// See [`ScalarUDFImpl::display_name`] for more details - #[deprecated( - since = "50.0.0", - note = "This method is unused and will be removed in a future release" - )] - pub fn display_name(&self, args: &[Expr]) -> Result { - #[expect(deprecated)] - self.inner.display_name(args) - } - /// Returns this function's schema_name. /// /// See [`ScalarUDFImpl::schema_name`] for more details @@ -255,12 +243,6 @@ impl ScalarUDF { self.inner.simplify(args, info) } - #[deprecated(since = "50.0.0", note = "Use `return_field_from_args` instead.")] - pub fn is_nullable(&self, args: &[Expr], schema: &dyn ExprSchema) -> bool { - #[expect(deprecated)] - self.inner.is_nullable(args, schema) - } - /// Return a preimage /// /// See [`ScalarUDFImpl::preimage`] for more details. @@ -551,22 +533,6 @@ pub trait ScalarUDFImpl: Debug + DynEq + DynHash + Send + Sync + Any { &[] } - /// Returns the user-defined display name of function, given the arguments - /// - /// This can be used to customize the output column name generated by this - /// function. - /// - /// Defaults to `name(args[0], args[1], ...)` - #[deprecated( - since = "50.0.0", - note = "This method is unused and will be removed in a future release" - )] - fn display_name(&self, args: &[Expr]) -> Result { - let names: Vec = args.iter().map(ToString::to_string).collect(); - // TODO: join with ", " to standardize the formatting of Vec, - Ok(format!("{}({})", self.name(), names.join(","))) - } - /// Returns the name of the column this expression would create /// /// See [`Expr::schema_name`] for details @@ -698,14 +664,6 @@ pub trait ScalarUDFImpl: Debug + DynEq + DynHash + Send + Sync + Any { Ok(Arc::new(Field::new(self.name(), return_type, true))) } - #[deprecated( - since = "45.0.0", - note = "Use `return_field_from_args` instead. if you use `is_nullable` that returns non-nullable with `return_type`, you would need to switch to `return_field_from_args`, you might have error" - )] - fn is_nullable(&self, _args: &[Expr], _schema: &dyn ExprSchema) -> bool { - true - } - /// Returns true if this function always returns NULL when any argument is /// NULL. /// @@ -1112,11 +1070,6 @@ impl ScalarUDFImpl for AliasedScalarUDFImpl { self.inner.name() } - fn display_name(&self, args: &[Expr]) -> Result { - #[expect(deprecated)] - self.inner.display_name(args) - } - fn schema_name(&self, args: &[Expr]) -> Result { self.inner.schema_name(args) } @@ -1133,11 +1086,6 @@ impl ScalarUDFImpl for AliasedScalarUDFImpl { self.inner.return_field_from_args(args) } - fn is_nullable(&self, args: &[Expr], schema: &dyn ExprSchema) -> bool { - #[expect(deprecated)] - self.inner.is_nullable(args, schema) - } - fn is_strict(&self) -> bool { self.inner.is_strict() } diff --git a/datafusion/functions-nested/src/extract.rs b/datafusion/functions-nested/src/extract.rs index cb7a316b289a9..deafb08c3f1ab 100644 --- a/datafusion/functions-nested/src/extract.rs +++ b/datafusion/functions-nested/src/extract.rs @@ -135,15 +135,6 @@ impl ScalarUDFImpl for ArrayElement { "array_element" } - fn display_name(&self, args: &[Expr]) -> Result { - let args_name = args.iter().map(ToString::to_string).collect::>(); - if args_name.len() != 2 { - return exec_err!("expect 2 args, got {}", args_name.len()); - } - - Ok(format!("{}[{}]", args_name[0], args_name[1])) - } - fn schema_name(&self, args: &[Expr]) -> Result { let args_name = args .iter() @@ -351,15 +342,6 @@ impl ArraySlice { } impl ScalarUDFImpl for ArraySlice { - fn display_name(&self, args: &[Expr]) -> Result { - let args_name = args.iter().map(ToString::to_string).collect::>(); - if let Some((arr, indexes)) = args_name.split_first() { - Ok(format!("{arr}[{}]", indexes.join(":"))) - } else { - exec_err!("no argument") - } - } - fn schema_name(&self, args: &[Expr]) -> Result { let args_name = args .iter() diff --git a/datafusion/functions/src/core/getfield.rs b/datafusion/functions/src/core/getfield.rs index 6ec874fb672d1..388daa32bf067 100644 --- a/datafusion/functions/src/core/getfield.rs +++ b/datafusion/functions/src/core/getfield.rs @@ -380,26 +380,6 @@ impl ScalarUDFImpl for GetFieldFunc { "get_field" } - fn display_name(&self, args: &[Expr]) -> Result { - if args.len() < 2 { - return exec_err!( - "get_field requires at least 2 arguments, got {}", - args.len() - ); - } - - let base = &args[0]; - let field_names: Vec = args[1..] - .iter() - .map(|f| match f { - Expr::Literal(name, _) => name.to_string(), - other => other.schema_name().to_string(), - }) - .collect(); - - Ok(format!("{}[{}]", base, field_names.join("]["))) - } - fn schema_name(&self, args: &[Expr]) -> Result { if args.len() < 2 { return exec_err!(