Skip to content

Commit 77ae93d

Browse files
Ben Chambersjorgecarleitao
authored andcommitted
ARROW-11394: [Rust] Tests for Slice & Concat
I took a stab at adding some tests for concat (and the underlying MutableArrayData) that cover the use case of the array having an offset. I had some problems with the assertions on the string array which makes me think this isn't fully fixed, but I wanted to put it up and see if anyone had suggestions for how to address this. Closes #9339 from bjchambers/ARROW-11394-slice-concat Authored-by: Ben Chambers <[email protected]> Signed-off-by: Jorge C. Leitao <[email protected]>
1 parent b18c567 commit 77ae93d

File tree

3 files changed

+184
-5
lines changed

3 files changed

+184
-5
lines changed

rust/arrow/src/array/transform/mod.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,46 @@ mod tests {
714714
assert_eq!(array, expected)
715715
}
716716

717+
#[test]
718+
fn test_struct_offset() {
719+
let strings: ArrayRef = Arc::new(StringArray::from(vec![
720+
Some("joe"),
721+
None,
722+
None,
723+
Some("mark"),
724+
Some("doe"),
725+
]));
726+
let ints: ArrayRef = Arc::new(Int32Array::from(vec![
727+
Some(1),
728+
Some(2),
729+
Some(3),
730+
Some(4),
731+
Some(5),
732+
]));
733+
734+
let array =
735+
StructArray::try_from(vec![("f1", strings.clone()), ("f2", ints.clone())])
736+
.unwrap()
737+
.slice(1, 3)
738+
.data();
739+
let arrays = vec![array.as_ref()];
740+
let mut mutable = MutableArrayData::new(arrays, false, 0);
741+
742+
mutable.extend(0, 1, 3);
743+
let data = mutable.freeze();
744+
let array = StructArray::from(Arc::new(data));
745+
746+
let expected_strings: ArrayRef =
747+
Arc::new(StringArray::from(vec![None, Some("mark")]));
748+
let expected = StructArray::try_from(vec![
749+
("f1", expected_strings),
750+
("f2", ints.slice(2, 2)),
751+
])
752+
.unwrap();
753+
754+
assert_eq!(array, expected);
755+
}
756+
717757
#[test]
718758
fn test_struct_nulls() {
719759
let strings: ArrayRef = Arc::new(StringArray::from(vec![

rust/arrow/src/array/transform/structure.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,13 @@ pub(super) fn build_extend(array: &ArrayData) -> Extend {
2626
index: usize,
2727
start: usize,
2828
len: usize| {
29-
mutable
30-
.child_data
31-
.iter_mut()
32-
.for_each(|child| child.extend(index, start, start + len))
29+
mutable.child_data.iter_mut().for_each(|child| {
30+
child.extend(
31+
index,
32+
array.offset() + start,
33+
array.offset() + start + len,
34+
)
35+
})
3336
},
3437
)
3538
} else {
@@ -38,7 +41,7 @@ pub(super) fn build_extend(array: &ArrayData) -> Extend {
3841
index: usize,
3942
start: usize,
4043
len: usize| {
41-
(start..start + len).for_each(|i| {
44+
(array.offset() + start..array.offset() + start + len).for_each(|i| {
4245
if array.is_valid(i) {
4346
mutable
4447
.child_data

rust/arrow/src/compute/kernels/concat.rs

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,40 @@ mod tests {
157157
Ok(())
158158
}
159159

160+
#[test]
161+
fn test_concat_primitive_array_slices() -> Result<()> {
162+
let input_1 = PrimitiveArray::<Int64Type>::from(vec![
163+
Some(-1),
164+
Some(-1),
165+
Some(2),
166+
None,
167+
None,
168+
])
169+
.slice(1, 3);
170+
171+
let input_2 = PrimitiveArray::<Int64Type>::from(vec![
172+
Some(101),
173+
Some(102),
174+
Some(103),
175+
None,
176+
])
177+
.slice(1, 3);
178+
let arr = concat(&[input_1.as_ref(), input_2.as_ref()])?;
179+
180+
let expected_output = Arc::new(PrimitiveArray::<Int64Type>::from(vec![
181+
Some(-1),
182+
Some(2),
183+
None,
184+
Some(102),
185+
Some(103),
186+
None,
187+
])) as ArrayRef;
188+
189+
assert_eq!(&arr, &expected_output);
190+
191+
Ok(())
192+
}
193+
160194
#[test]
161195
fn test_concat_boolean_primitive_arrays() -> Result<()> {
162196
let arr = concat(&[
@@ -254,4 +288,106 @@ mod tests {
254288

255289
Ok(())
256290
}
291+
292+
#[test]
293+
fn test_concat_struct_arrays() -> Result<()> {
294+
let field = Field::new("field", DataType::Int64, true);
295+
let input_primitive_1: ArrayRef =
296+
Arc::new(PrimitiveArray::<Int64Type>::from(vec![
297+
Some(-1),
298+
Some(-1),
299+
Some(2),
300+
None,
301+
None,
302+
]));
303+
let input_struct_1 = StructArray::from(vec![(field.clone(), input_primitive_1)]);
304+
305+
let input_primitive_2: ArrayRef =
306+
Arc::new(PrimitiveArray::<Int64Type>::from(vec![
307+
Some(101),
308+
Some(102),
309+
Some(103),
310+
None,
311+
]));
312+
let input_struct_2 = StructArray::from(vec![(field.clone(), input_primitive_2)]);
313+
314+
let input_primitive_3: ArrayRef =
315+
Arc::new(PrimitiveArray::<Int64Type>::from(vec![
316+
Some(256),
317+
Some(512),
318+
Some(1024),
319+
]));
320+
let input_struct_3 = StructArray::from(vec![(field, input_primitive_3)]);
321+
322+
let arr = concat(&[&input_struct_1, &input_struct_2, &input_struct_3])?;
323+
324+
let expected_primitive_output = Arc::new(PrimitiveArray::<Int64Type>::from(vec![
325+
Some(-1),
326+
Some(-1),
327+
Some(2),
328+
None,
329+
None,
330+
Some(101),
331+
Some(102),
332+
Some(103),
333+
None,
334+
Some(256),
335+
Some(512),
336+
Some(1024),
337+
])) as ArrayRef;
338+
339+
let actual_primitive = arr
340+
.as_any()
341+
.downcast_ref::<StructArray>()
342+
.unwrap()
343+
.column(0);
344+
assert_eq!(actual_primitive, &expected_primitive_output);
345+
346+
Ok(())
347+
}
348+
349+
#[test]
350+
fn test_concat_struct_array_slices() -> Result<()> {
351+
let field = Field::new("field", DataType::Int64, true);
352+
let input_primitive_1: ArrayRef =
353+
Arc::new(PrimitiveArray::<Int64Type>::from(vec![
354+
Some(-1),
355+
Some(-1),
356+
Some(2),
357+
None,
358+
None,
359+
]));
360+
let input_struct_1 = StructArray::from(vec![(field.clone(), input_primitive_1)]);
361+
362+
let input_primitive_2: ArrayRef =
363+
Arc::new(PrimitiveArray::<Int64Type>::from(vec![
364+
Some(101),
365+
Some(102),
366+
Some(103),
367+
None,
368+
]));
369+
let input_struct_2 = StructArray::from(vec![(field, input_primitive_2)]);
370+
371+
let arr = concat(&[
372+
input_struct_1.slice(1, 3).as_ref(),
373+
input_struct_2.slice(1, 2).as_ref(),
374+
])?;
375+
376+
let expected_primitive_output = Arc::new(PrimitiveArray::<Int64Type>::from(vec![
377+
Some(-1),
378+
Some(2),
379+
None,
380+
Some(102),
381+
Some(103),
382+
])) as ArrayRef;
383+
384+
let actual_primitive = arr
385+
.as_any()
386+
.downcast_ref::<StructArray>()
387+
.unwrap()
388+
.column(0);
389+
assert_eq!(actual_primitive, &expected_primitive_output);
390+
391+
Ok(())
392+
}
257393
}

0 commit comments

Comments
 (0)