Skip to content

Commit 84a2c59

Browse files
authored
Merge pull request #105 from DataDog/branch-52-cherry-pick-array-element-null-handling
Use ListArray nullability instead of offsets.
2 parents 4a36e6b + b86d27d commit 84a2c59

1 file changed

Lines changed: 56 additions & 7 deletions

File tree

datafusion/functions-nested/src/extract.rs

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ where
263263
let len = end - start;
264264

265265
// array is null
266-
if len == O::usize_as(0) {
266+
if array.is_null(row_index) {
267267
mutable.extend_nulls(1);
268268
continue;
269269
}
@@ -1090,11 +1090,9 @@ where
10901090

10911091
for (row_index, offset_window) in array.offsets().windows(2).enumerate() {
10921092
let start = offset_window[0];
1093-
let end = offset_window[1];
1094-
let len = end - start;
10951093

10961094
// array is null
1097-
if len == O::usize_as(0) {
1095+
if array.is_null(row_index) {
10981096
mutable.extend_nulls(1);
10991097
continue;
11001098
}
@@ -1127,14 +1125,18 @@ where
11271125

11281126
#[cfg(test)]
11291127
mod tests {
1130-
use super::{array_element_udf, general_list_view_array_slice};
1128+
use super::{
1129+
array_element_udf, general_array_any_value, general_array_element,
1130+
general_list_view_array_slice,
1131+
};
11311132
use arrow::array::{
11321133
Array, ArrayRef, GenericListViewArray, Int32Array, Int64Array, ListViewArray,
11331134
cast::AsArray,
11341135
};
1135-
use arrow::buffer::ScalarBuffer;
1136+
use arrow::array::{ListArray, RecordBatch};
1137+
use arrow::buffer::{NullBuffer, OffsetBuffer, ScalarBuffer};
11361138
use arrow::datatypes::{DataType, Field};
1137-
use datafusion_common::{Column, DFSchema, Result};
1139+
use datafusion_common::{Column, DFSchema, Result, assert_batches_eq};
11381140
use datafusion_expr::expr::ScalarFunction;
11391141
use datafusion_expr::{Expr, ExprSchemable};
11401142
use std::collections::HashMap;
@@ -1195,6 +1197,53 @@ mod tests {
11951197
);
11961198
}
11971199

1200+
#[test]
1201+
fn test_array_element_null_handling() -> Result<()> {
1202+
let values = Arc::new(Int32Array::from(vec![1, 2, 3, 4, 5]));
1203+
let offsets = OffsetBuffer::new(ScalarBuffer::from(vec![0, 3, 4, 5]));
1204+
let nulls = NullBuffer::from(vec![true, false, true]);
1205+
let field = Arc::new(Field::new("item", DataType::Int32, true));
1206+
1207+
let list_array = ListArray::new(field, offsets, values, Some(nulls));
1208+
let indexes = Int64Array::from(vec![1, 1, 1]);
1209+
1210+
let result = general_array_element(&list_array, &indexes)?;
1211+
1212+
let expected = [
1213+
"+--------+",
1214+
"| result |",
1215+
"+--------+",
1216+
"| 1 |",
1217+
"| |",
1218+
"| 5 |",
1219+
"+--------+",
1220+
];
1221+
1222+
let batch = RecordBatch::try_from_iter([("result", result)])?;
1223+
1224+
assert_batches_eq!(expected, &[batch]);
1225+
1226+
Ok(())
1227+
}
1228+
1229+
#[test]
1230+
fn test_array_any_null_handling() -> Result<()> {
1231+
let values: ArrayRef = Arc::new(Int32Array::from(vec![1, 2, 3, 4, 5]));
1232+
let offsets = OffsetBuffer::new(ScalarBuffer::from(vec![0, 3, 4, 5]));
1233+
let nulls = NullBuffer::from(vec![true, false, true]);
1234+
let field = Arc::new(Field::new("item", DataType::Int32, true));
1235+
1236+
let list_array = ListArray::new(field, offsets, values, Some(nulls));
1237+
1238+
let result = general_array_any_value(&list_array)?;
1239+
1240+
assert!(!result.is_null(0));
1241+
assert!(result.is_null(1));
1242+
assert!(!result.is_null(2));
1243+
1244+
Ok(())
1245+
}
1246+
11981247
#[test]
11991248
fn test_array_slice_list_view_basic() -> Result<()> {
12001249
let values: ArrayRef = Arc::new(Int32Array::from(vec![1, 2, 3, 4, 5]));

0 commit comments

Comments
 (0)