From 19d892a91134300b29738142d6d9f4faf46a7225 Mon Sep 17 00:00:00 2001 From: SteveLauC Date: Thu, 29 Feb 2024 00:19:42 +0800 Subject: [PATCH] fix: panic in isnan() when no args are given (#9377) * fix: panic in isnan() when no args are given * test: add sqllogictest for abs/acos/isnan --- datafusion/functions/src/math/nans.rs | 23 ++++++++++++++----- datafusion/sqllogictest/test_files/scalar.slt | 10 ++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/datafusion/functions/src/math/nans.rs b/datafusion/functions/src/math/nans.rs index 96a50f9aa568..73fa4998c14b 100644 --- a/datafusion/functions/src/math/nans.rs +++ b/datafusion/functions/src/math/nans.rs @@ -18,12 +18,12 @@ //! Math function: `isnan()`. use arrow::datatypes::DataType; -use datafusion_common::{exec_err, DataFusionError, Result}; +use datafusion_common::{exec_err, DataFusionError, Result, plan_datafusion_err}; use datafusion_expr::ColumnarValue; use arrow::array::{ArrayRef, BooleanArray, Float32Array, Float64Array}; use datafusion_expr::TypeSignature::*; -use datafusion_expr::{ScalarUDFImpl, Signature, Volatility}; +use datafusion_expr::{ScalarUDFImpl, Signature, Volatility, utils::generate_signature_error_msg}; use std::any::Any; use std::sync::Arc; @@ -57,7 +57,18 @@ impl ScalarUDFImpl for IsNanFunc { &self.signature } - fn return_type(&self, _arg_types: &[DataType]) -> Result { + fn return_type(&self, arg_types: &[DataType]) -> Result { + if arg_types.len() != 1 { + return Err(plan_datafusion_err!( + "{}", + generate_signature_error_msg( + self.name(), + self.signature().clone(), + arg_types, + ) + )); + } + Ok(DataType::Boolean) } @@ -68,7 +79,7 @@ impl ScalarUDFImpl for IsNanFunc { DataType::Float64 => { Arc::new(make_function_scalar_inputs_return_type!( &args[0], - "x", + self.name(), Float64Array, BooleanArray, { f64::is_nan } @@ -77,13 +88,13 @@ impl ScalarUDFImpl for IsNanFunc { DataType::Float32 => { Arc::new(make_function_scalar_inputs_return_type!( &args[0], - "x", + self.name(), Float32Array, BooleanArray, { f32::is_nan } )) } - other => return exec_err!("Unsupported data type {other:?} for function isnan"), + other => return exec_err!("Unsupported data type {other:?} for function {}", self.name()), }; Ok(ColumnarValue::Array(arr)) } diff --git a/datafusion/sqllogictest/test_files/scalar.slt b/datafusion/sqllogictest/test_files/scalar.slt index aab910700075..45334f5b402f 100644 --- a/datafusion/sqllogictest/test_files/scalar.slt +++ b/datafusion/sqllogictest/test_files/scalar.slt @@ -1874,6 +1874,16 @@ SELECT arrow_typeof(1, 1); statement error Error during planning: No function matches the given name and argument types 'power\(Int64, Int64, Int64\)'. You might need to add explicit type casts.\n\tCandidate functions:\n\tpower\(Int64, Int64\)\n\tpower\(Float64, Float64\) SELECT power(1, 2, 3); +# The following functions need 1 argument +statement error Error during planning: No function matches the given name and argument types 'abs\(\)'. You might need to add explicit type casts.\n\tCandidate functions:\n\tabs\(Any\) +SELECT abs(); + +statement error Error during planning: No function matches the given name and argument types 'acos\(\)'. You might need to add explicit type casts.\n\tCandidate functions:\n\tacos\(Float64/Float32\) +SELECT acos(); + +statement error Error during planning: No function matches the given name and argument types 'isnan\(\)'. You might need to add explicit type casts.\n\tCandidate functions:\n\tisnan\(Float32\)\n\tisnan\(Float64\) +SELECT isnan(); + # turn off enable_ident_normalization statement ok set datafusion.sql_parser.enable_ident_normalization = false;