From 405b99ce7b1ba29dd1d406f4554d84b9f756d604 Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Mon, 23 Dec 2024 09:31:48 -0500 Subject: [PATCH] Improve error messages for incorrect zero argument signatures (#13881) * Improve error messages for incorrect zero argument signatures * fix errors * fix fmt --- datafusion/expr-common/src/signature.rs | 9 +++ .../expr/src/type_coercion/functions.rs | 71 +++++++++---------- 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/datafusion/expr-common/src/signature.rs b/datafusion/expr-common/src/signature.rs index 77ba1858e35b..56f3029a4d7a 100644 --- a/datafusion/expr-common/src/signature.rs +++ b/datafusion/expr-common/src/signature.rs @@ -351,6 +351,15 @@ impl TypeSignature { } } + /// Returns true if the signature currently supports or used to supported 0 + /// input arguments in a previous version of DataFusion. + pub fn used_to_support_zero_arguments(&self) -> bool { + match &self { + TypeSignature::Any(num) => *num == 0, + _ => self.supports_zero_argument(), + } + } + /// get all possible types for the given `TypeSignature` pub fn get_possible_types(&self) -> Vec> { match self { diff --git a/datafusion/expr/src/type_coercion/functions.rs b/datafusion/expr/src/type_coercion/functions.rs index 7d2906e1731b..38e7106e6e64 100644 --- a/datafusion/expr/src/type_coercion/functions.rs +++ b/datafusion/expr/src/type_coercion/functions.rs @@ -50,17 +50,21 @@ pub fn data_types_with_scalar_udf( func: &ScalarUDF, ) -> Result> { let signature = func.signature(); + let type_signature = &signature.type_signature; if current_types.is_empty() { - if signature.type_signature.supports_zero_argument() { + if type_signature.supports_zero_argument() { return Ok(vec![]); + } else if type_signature.used_to_support_zero_arguments() { + // Special error to help during upgrade: https://github.com/apache/datafusion/issues/13763 + return plan_err!("{} does not support zero arguments. Use TypeSignature::Nullary for zero arguments.", func.name()); } else { return plan_err!("{} does not support zero arguments.", func.name()); } } let valid_types = - get_valid_types_with_scalar_udf(&signature.type_signature, current_types, func)?; + get_valid_types_with_scalar_udf(type_signature, current_types, func)?; if valid_types .iter() @@ -69,12 +73,7 @@ pub fn data_types_with_scalar_udf( return Ok(current_types.to_vec()); } - try_coerce_types( - func.name(), - valid_types, - current_types, - &signature.type_signature, - ) + try_coerce_types(func.name(), valid_types, current_types, type_signature) } /// Performs type coercion for aggregate function arguments. @@ -89,20 +88,21 @@ pub fn data_types_with_aggregate_udf( func: &AggregateUDF, ) -> Result> { let signature = func.signature(); + let type_signature = &signature.type_signature; if current_types.is_empty() { - if signature.type_signature.supports_zero_argument() { + if type_signature.supports_zero_argument() { return Ok(vec![]); + } else if type_signature.used_to_support_zero_arguments() { + // Special error to help during upgrade: https://github.com/apache/datafusion/issues/13763 + return plan_err!("{} does not support zero arguments. Use TypeSignature::Nullary for zero arguments.", func.name()); } else { return plan_err!("{} does not support zero arguments.", func.name()); } } - let valid_types = get_valid_types_with_aggregate_udf( - &signature.type_signature, - current_types, - func, - )?; + let valid_types = + get_valid_types_with_aggregate_udf(type_signature, current_types, func)?; if valid_types .iter() .any(|data_type| data_type == current_types) @@ -110,12 +110,7 @@ pub fn data_types_with_aggregate_udf( return Ok(current_types.to_vec()); } - try_coerce_types( - func.name(), - valid_types, - current_types, - &signature.type_signature, - ) + try_coerce_types(func.name(), valid_types, current_types, type_signature) } /// Performs type coercion for window function arguments. @@ -130,17 +125,21 @@ pub fn data_types_with_window_udf( func: &WindowUDF, ) -> Result> { let signature = func.signature(); + let type_signature = &signature.type_signature; if current_types.is_empty() { - if signature.type_signature.supports_zero_argument() { + if type_signature.supports_zero_argument() { return Ok(vec![]); + } else if type_signature.used_to_support_zero_arguments() { + // Special error to help during upgrade: https://github.com/apache/datafusion/issues/13763 + return plan_err!("{} does not support zero arguments. Use TypeSignature::Nullary for zero arguments.", func.name()); } else { return plan_err!("{} does not support zero arguments.", func.name()); } } let valid_types = - get_valid_types_with_window_udf(&signature.type_signature, current_types, func)?; + get_valid_types_with_window_udf(type_signature, current_types, func)?; if valid_types .iter() .any(|data_type| data_type == current_types) @@ -148,12 +147,7 @@ pub fn data_types_with_window_udf( return Ok(current_types.to_vec()); } - try_coerce_types( - func.name(), - valid_types, - current_types, - &signature.type_signature, - ) + try_coerce_types(func.name(), valid_types, current_types, type_signature) } /// Performs type coercion for function arguments. @@ -168,18 +162,26 @@ pub fn data_types( current_types: &[DataType], signature: &Signature, ) -> Result> { + let type_signature = &signature.type_signature; + if current_types.is_empty() { - if signature.type_signature.supports_zero_argument() { + if type_signature.supports_zero_argument() { return Ok(vec![]); + } else if type_signature.used_to_support_zero_arguments() { + // Special error to help during upgrade: https://github.com/apache/datafusion/issues/13763 + return plan_err!( + "signature {:?} does not support zero arguments. Use TypeSignature::Nullary for zero arguments.", + type_signature + ); } else { return plan_err!( "signature {:?} does not support zero arguments.", - &signature.type_signature + type_signature ); } } - let valid_types = get_valid_types(&signature.type_signature, current_types)?; + let valid_types = get_valid_types(type_signature, current_types)?; if valid_types .iter() .any(|data_type| data_type == current_types) @@ -187,12 +189,7 @@ pub fn data_types( return Ok(current_types.to_vec()); } - try_coerce_types( - function_name, - valid_types, - current_types, - &signature.type_signature, - ) + try_coerce_types(function_name, valid_types, current_types, type_signature) } fn is_well_supported_signature(type_signature: &TypeSignature) -> bool {