Skip to content

Commit 027c978

Browse files
authored
Fix array_concat with NULL arrays (apache#16348) (#32)
1 parent d2745b8 commit 027c978

2 files changed

Lines changed: 52 additions & 3 deletions

File tree

datafusion/functions-nested/src/concat.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use std::sync::Arc;
2323
use crate::make_array::make_array_inner;
2424
use crate::utils::{align_array_dimensions, check_datatypes, make_scalar_function};
2525
use arrow::array::{
26-
Array, ArrayRef, Capacities, GenericListArray, MutableArrayData, NullArray,
26+
Array, ArrayData, ArrayRef, Capacities, GenericListArray, MutableArrayData,
2727
NullBufferBuilder, OffsetSizeTrait,
2828
};
2929
use arrow::buffer::OffsetBuffer;
@@ -42,6 +42,7 @@ use datafusion_expr::{
4242
ColumnarValue, Documentation, ScalarUDFImpl, Signature, Volatility,
4343
};
4444
use datafusion_macros::user_doc;
45+
use itertools::Itertools;
4546

4647
make_udf_expr_and_func!(
4748
ArrayAppend,
@@ -365,11 +366,23 @@ pub(crate) fn array_concat_inner(args: &[ArrayRef]) -> Result<ArrayRef> {
365366
_ => (),
366367
}
367368

368-
all_null = false
369+
if arg.null_count() < arg.len() {
370+
all_null = false;
371+
}
369372
}
370373

371374
if all_null {
372-
Ok(Arc::new(NullArray::new(args[0].len())))
375+
// Return a null array with the same type as the first non-null-type argument
376+
let return_type = args
377+
.iter()
378+
.map(|arg| arg.data_type())
379+
.find_or_first(|d| !d.is_null())
380+
.unwrap(); // Safe because args is non-empty
381+
382+
Ok(arrow::array::make_array(ArrayData::new_null(
383+
return_type,
384+
args[0].len(),
385+
)))
373386
} else if large_list {
374387
concat_internal::<i64>(args)
375388
} else {

datafusion/sqllogictest/test_files/array.slt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3070,6 +3070,42 @@ select array_concat([]);
30703070
----
30713071
[]
30723072

3073+
# test with NULL array
3074+
query ?
3075+
select array_concat(NULL::integer[]);
3076+
----
3077+
NULL
3078+
3079+
# test with multiple NULL arrays
3080+
query ?
3081+
select array_concat(NULL::integer[], NULL::integer[]);
3082+
----
3083+
NULL
3084+
3085+
# test with NULL LargeList
3086+
query ?
3087+
select array_concat(arrow_cast(NULL::string[], 'LargeList(Utf8)'));
3088+
----
3089+
NULL
3090+
3091+
# test with NULL FixedSizeList
3092+
query ?
3093+
select array_concat(arrow_cast(NULL::string[], 'FixedSizeList(2, Utf8)'));
3094+
----
3095+
NULL
3096+
3097+
# test with mix of NULL and empty arrays
3098+
query ?
3099+
select array_concat(NULL::integer[], []);
3100+
----
3101+
[]
3102+
3103+
# test with mix of NULL and non-empty arrays
3104+
query ?
3105+
select array_concat(NULL::integer[], [1, 2, 3]);
3106+
----
3107+
[1, 2, 3]
3108+
30733109
# Concatenating strings arrays
30743110
query ?
30753111
select array_concat(

0 commit comments

Comments
 (0)