Skip to content

Commit 661d211

Browse files
authored
Minor: Avoid recomputing compute_array_ndims in align_array_dimensions (#7963)
* Refactor align_array_dimensions Signed-off-by: jayzhan211 <jayzhan211@gmail.com> * address comment Signed-off-by: jayzhan211 <jayzhan211@gmail.com> * remove unwrap Signed-off-by: jayzhan211 <jayzhan211@gmail.com> * address comment Signed-off-by: jayzhan211 <jayzhan211@gmail.com> * fix rebase Signed-off-by: jayzhan211 <jayzhan211@gmail.com> --------- Signed-off-by: jayzhan211 <jayzhan211@gmail.com>
1 parent 0fa4ce9 commit 661d211

File tree

1 file changed

+56
-19
lines changed

1 file changed

+56
-19
lines changed

datafusion/physical-expr/src/array_expressions.rs

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -725,35 +725,31 @@ pub fn array_prepend(args: &[ArrayRef]) -> Result<ArrayRef> {
725725
}
726726

727727
fn align_array_dimensions(args: Vec<ArrayRef>) -> Result<Vec<ArrayRef>> {
728-
// Find the maximum number of dimensions
729-
let max_ndim: u64 = (*args
728+
let args_ndim = args
730729
.iter()
731-
.map(|arr| compute_array_ndims(Some(arr.clone())))
732-
.collect::<Result<Vec<Option<u64>>>>()?
733-
.iter()
734-
.max()
735-
.unwrap())
736-
.unwrap();
730+
.map(|arg| compute_array_ndims(Some(arg.to_owned())))
731+
.collect::<Result<Vec<_>>>()?
732+
.into_iter()
733+
.map(|x| x.unwrap_or(0))
734+
.collect::<Vec<_>>();
735+
let max_ndim = args_ndim.iter().max().unwrap_or(&0);
737736

738737
// Align the dimensions of the arrays
739738
let aligned_args: Result<Vec<ArrayRef>> = args
740739
.into_iter()
741-
.map(|array| {
742-
let ndim = compute_array_ndims(Some(array.clone()))?.unwrap();
740+
.zip(args_ndim.iter())
741+
.map(|(array, ndim)| {
743742
if ndim < max_ndim {
744743
let mut aligned_array = array.clone();
745744
for _ in 0..(max_ndim - ndim) {
746-
let data_type = aligned_array.as_ref().data_type().clone();
747-
let offsets: Vec<i32> =
748-
(0..downcast_arg!(aligned_array, ListArray).offsets().len())
749-
.map(|i| i as i32)
750-
.collect();
751-
let field = Arc::new(Field::new("item", data_type, true));
745+
let data_type = aligned_array.data_type().to_owned();
746+
let array_lengths = vec![1; aligned_array.len()];
747+
let offsets = OffsetBuffer::<i32>::from_lengths(array_lengths);
752748

753749
aligned_array = Arc::new(ListArray::try_new(
754-
field,
755-
OffsetBuffer::new(offsets.into()),
756-
Arc::new(aligned_array.clone()),
750+
Arc::new(Field::new("item", data_type, true)),
751+
offsets,
752+
aligned_array,
757753
None,
758754
)?)
759755
}
@@ -1923,6 +1919,47 @@ mod tests {
19231919
use arrow::datatypes::Int64Type;
19241920
use datafusion_common::cast::as_uint64_array;
19251921

1922+
#[test]
1923+
fn test_align_array_dimensions() {
1924+
let array1d_1 =
1925+
Arc::new(ListArray::from_iter_primitive::<Int64Type, _, _>(vec![
1926+
Some(vec![Some(1), Some(2), Some(3)]),
1927+
Some(vec![Some(4), Some(5)]),
1928+
]));
1929+
let array1d_2 =
1930+
Arc::new(ListArray::from_iter_primitive::<Int64Type, _, _>(vec![
1931+
Some(vec![Some(6), Some(7), Some(8)]),
1932+
]));
1933+
1934+
let array2d_1 = Arc::new(array_into_list_array(array1d_1.clone())) as ArrayRef;
1935+
let array2d_2 = Arc::new(array_into_list_array(array1d_2.clone())) as ArrayRef;
1936+
1937+
let res =
1938+
align_array_dimensions(vec![array1d_1.to_owned(), array2d_2.to_owned()])
1939+
.unwrap();
1940+
1941+
let expected = as_list_array(&array2d_1).unwrap();
1942+
let expected_dim = compute_array_ndims(Some(array2d_1.to_owned())).unwrap();
1943+
assert_ne!(as_list_array(&res[0]).unwrap(), expected);
1944+
assert_eq!(
1945+
compute_array_ndims(Some(res[0].clone())).unwrap(),
1946+
expected_dim
1947+
);
1948+
1949+
let array3d_1 = Arc::new(array_into_list_array(array2d_1)) as ArrayRef;
1950+
let array3d_2 = array_into_list_array(array2d_2.to_owned());
1951+
let res =
1952+
align_array_dimensions(vec![array1d_1, Arc::new(array3d_2.clone())]).unwrap();
1953+
1954+
let expected = as_list_array(&array3d_1).unwrap();
1955+
let expected_dim = compute_array_ndims(Some(array3d_1.to_owned())).unwrap();
1956+
assert_ne!(as_list_array(&res[0]).unwrap(), expected);
1957+
assert_eq!(
1958+
compute_array_ndims(Some(res[0].clone())).unwrap(),
1959+
expected_dim
1960+
);
1961+
}
1962+
19261963
#[test]
19271964
fn test_array() {
19281965
// make_array(1, 2, 3) = [1, 2, 3]

0 commit comments

Comments
 (0)