From 7dc4a4090d158d5f97cab9c08cfded7c5c09ad66 Mon Sep 17 00:00:00 2001 From: JuieeAJaviya Date: Sun, 4 Jan 2026 10:18:04 +0530 Subject: [PATCH 1/2] Fix concat() to support array inputs --- datafusion/functions/src/string/concat.rs | 52 +++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/datafusion/functions/src/string/concat.rs b/datafusion/functions/src/string/concat.rs index 42d455a05760a..2030018a69846 100644 --- a/datafusion/functions/src/string/concat.rs +++ b/datafusion/functions/src/string/concat.rs @@ -108,6 +108,17 @@ impl ScalarUDFImpl for ConcatFunc { fn invoke_with_args(&self, args: ScalarFunctionArgs) -> Result { let ScalarFunctionArgs { args, .. } = args; + // If all arguments are arrays, delegate to array_concat + let all_arrays = args.iter().all(|arg| matches!(arg, ColumnarValue::Array(_))); + if all_arrays { + use crate::array::array_concat; + return array_concat().invoke_with_args(ScalarFunctionArgs { + args, + ..Default::default() + }); + } + + let mut return_datatype = DataType::Utf8; args.iter().for_each(|col| { if col.data_type() == DataType::Utf8View { @@ -385,6 +396,47 @@ mod tests { use arrow::datatypes::Field; use datafusion_common::config::ConfigOptions; + #[test] + fn concat_array_should_match_array_concat() -> Result<()> { + use arrow::array::Int64Array; + use arrow::datatypes::{DataType, Field}; + + let a = ColumnarValue::Array(Arc::new( + Int64Array::from(vec![Some(1), Some(2), Some(3)]) + )); + let b = ColumnarValue::Array(Arc::new( + Int64Array::from(vec![Some(4), Some(5)]) + )); + + let args = ScalarFunctionArgs { + args: vec![a, b], + arg_fields: vec![ + Arc::new(Field::new("a", DataType::Int64, true)), + Arc::new(Field::new("b", DataType::Int64, true)), + ], + number_rows: 3, + return_field: Field::new( + "f", + DataType::List(Arc::new(Field::new("item", DataType::Int64, true))), + true, + ) + .into(), + config_options: Arc::new(ConfigOptions::default()), + }; + + let result = ConcatFunc::new().invoke_with_args(args)?; + + match result { + ColumnarValue::Array(array) => { + assert_eq!(array.len(), 5); // [1,2,3,4,5] + } + _ => panic!("Expected array output"), + } + + Ok(()) + } + + #[test] fn test_functions() -> Result<()> { test_function!( From e1dcc25d789dfc32386156374f5f147209f2d1a3 Mon Sep 17 00:00:00 2001 From: JuieeAJaviya Date: Tue, 6 Jan 2026 12:42:33 +0530 Subject: [PATCH 2/2] Fix CI failures and improve concat array tests --- datafusion/functions/src/string/concat.rs | 31 +++++++++++++++-------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/datafusion/functions/src/string/concat.rs b/datafusion/functions/src/string/concat.rs index 2030018a69846..4cca065945352 100644 --- a/datafusion/functions/src/string/concat.rs +++ b/datafusion/functions/src/string/concat.rs @@ -20,6 +20,7 @@ use arrow::datatypes::DataType; use datafusion_expr::sort_properties::ExprProperties; use std::any::Any; use std::sync::Arc; +use crate::array::array_concat; use crate::string::concat; use crate::strings::{ @@ -108,15 +109,14 @@ impl ScalarUDFImpl for ConcatFunc { fn invoke_with_args(&self, args: ScalarFunctionArgs) -> Result { let ScalarFunctionArgs { args, .. } = args; + // If all arguments are arrays, delegate to array_concat // If all arguments are arrays, delegate to array_concat let all_arrays = args.iter().all(|arg| matches!(arg, ColumnarValue::Array(_))); - if all_arrays { - use crate::array::array_concat; - return array_concat().invoke_with_args(ScalarFunctionArgs { - args, - ..Default::default() - }); - } + if all_arrays { + use crate::array::array_concat; + return array_concat().invoke_with_args(args.into()); + } + let mut return_datatype = DataType::Utf8; @@ -399,7 +399,6 @@ mod tests { #[test] fn concat_array_should_match_array_concat() -> Result<()> { use arrow::array::Int64Array; - use arrow::datatypes::{DataType, Field}; let a = ColumnarValue::Array(Arc::new( Int64Array::from(vec![Some(1), Some(2), Some(3)]) @@ -417,7 +416,7 @@ mod tests { number_rows: 3, return_field: Field::new( "f", - DataType::List(Arc::new(Field::new("item", DataType::Int64, true))), + List(Arc::new(Field::new("item", Int64, true))), true, ) .into(), @@ -428,7 +427,19 @@ mod tests { match result { ColumnarValue::Array(array) => { - assert_eq!(array.len(), 5); // [1,2,3,4,5] + let values = array + .as_any() + .downcast_ref::() + .unwrap(); + + let inner = values + .value(0) + .as_any() + .downcast_ref::() + .unwrap(); + + assert_eq!(inner.values(), &[1, 2, 3, 4, 5]); + } _ => panic!("Expected array output"), }