1use std::fmt::Display;
21use std::mem::ManuallyDrop;
22use std::sync::Arc;
23
24use arrow_array::builder::{BufferBuilder, UInt32Builder};
25use arrow_array::cast::AsArray;
26use arrow_array::types::*;
27use arrow_array::*;
28use arrow_buffer::{
29 ArrowNativeType, BooleanBuffer, Buffer, MutableBuffer, NullBuffer, OffsetBuffer, RunEndBuffer,
30 ScalarBuffer, bit_util,
31};
32use arrow_cmp::make_comparator;
33use arrow_data::transform::MutableArrayData;
34use arrow_schema::{ArrowError, DataType, FieldRef, SortOptions, UnionMode};
35
36use num_traits::Zero;
37
38pub fn take(
90 values: &dyn Array,
91 indices: &dyn Array,
92 options: Option<TakeOptions>,
93) -> Result<ArrayRef, ArrowError> {
94 let options = options.unwrap_or_default();
95 downcast_integer_array!(
96 indices => {
97 if options.check_bounds {
98 check_bounds(values.len(), indices)?;
99 }
100 let indices = indices.to_indices();
101 take_impl(values, &indices)
102 },
103 d => Err(ArrowError::InvalidArgumentError(format!("Take only supported for integers, got {d:?}")))
104 )
105}
106
107pub fn take_arrays(
156 arrays: &[ArrayRef],
157 indices: &dyn Array,
158 options: Option<TakeOptions>,
159) -> Result<Vec<ArrayRef>, ArrowError> {
160 arrays
161 .iter()
162 .map(|array| take(array.as_ref(), indices, options.clone()))
163 .collect()
164}
165
166fn check_bounds<T: ArrowPrimitiveType>(
168 len: usize,
169 indices: &PrimitiveArray<T>,
170) -> Result<(), ArrowError>
171where
172 T::Native: Display,
173{
174 let len = match T::Native::from_usize(len) {
175 Some(len) => len,
176 None => {
177 if T::DATA_TYPE.is_integer() {
178 return Ok(());
180 } else {
181 return Err(ArrowError::ComputeError("Cast to usize failed".to_string()));
182 }
183 }
184 };
185
186 if indices.null_count() > 0 {
187 indices.iter().flatten().try_for_each(|index| {
188 if index >= len {
189 return Err(ArrowError::ComputeError(format!(
190 "Array index out of bounds, cannot get item at index {index} from {len} entries"
191 )));
192 }
193 Ok(())
194 })
195 } else {
196 let in_bounds = indices.values().iter().fold(true, |in_bounds, &i| {
197 in_bounds & (i >= T::Native::ZERO) & (i < len)
198 });
199
200 if !in_bounds {
201 for &index in indices.values() {
202 if index < T::Native::ZERO || index >= len {
203 return Err(ArrowError::ComputeError(format!(
204 "Array index out of bounds, cannot get item at index {index} from {len} entries"
205 )));
206 }
207 }
208 }
209
210 Ok(())
211 }
212}
213
214#[inline(never)]
215fn take_impl<IndexType: ArrowPrimitiveType>(
216 values: &dyn Array,
217 indices: &PrimitiveArray<IndexType>,
218) -> Result<ArrayRef, ArrowError> {
219 if indices.is_empty() {
220 return Ok(new_empty_array(values.data_type()));
221 }
222 downcast_primitive_array! {
223 values => Ok(Arc::new(take_primitive(values, indices)?)),
224 DataType::Boolean => {
225 let values = values.as_any().downcast_ref::<BooleanArray>().unwrap();
226 Ok(Arc::new(take_boolean(values, indices)))
227 }
228 DataType::Utf8 => {
229 Ok(Arc::new(take_bytes(values.as_string::<i32>(), indices)?))
230 }
231 DataType::LargeUtf8 => {
232 Ok(Arc::new(take_bytes(values.as_string::<i64>(), indices)?))
233 }
234 DataType::Utf8View => {
235 Ok(Arc::new(take_byte_view(values.as_string_view(), indices)?))
236 }
237 DataType::List(_) => {
238 Ok(Arc::new(take_list::<_, Int32Type>(values.as_list(), indices)?))
239 }
240 DataType::LargeList(_) => {
241 Ok(Arc::new(take_list::<_, Int64Type>(values.as_list(), indices)?))
242 }
243 DataType::ListView(_) => {
244 Ok(Arc::new(take_list_view::<_, Int32Type>(values.as_list_view(), indices)?))
245 }
246 DataType::LargeListView(_) => {
247 Ok(Arc::new(take_list_view::<_, Int64Type>(values.as_list_view(), indices)?))
248 }
249 DataType::FixedSizeList(_, length) => {
250 let values = values
251 .as_any()
252 .downcast_ref::<FixedSizeListArray>()
253 .unwrap();
254 Ok(Arc::new(take_fixed_size_list(
255 values,
256 indices,
257 *length as u32,
258 )?))
259 }
260 DataType::Map(field, ordered) => {
261 let list_arr = ListArray::from(values.as_map().clone());
262 let list_data = take_list::<_, Int32Type>(&list_arr, indices)?;
263 let (_, offsets, entries, nulls) = list_data.into_parts();
264 let entries = entries.as_struct().clone();
265 Ok(Arc::new(MapArray::try_new(
266 field.clone(),
267 offsets,
268 entries,
269 nulls,
270 *ordered,
271 )?))
272 }
273 DataType::Struct(fields) => {
274 let array: &StructArray = values.as_struct();
275 let arrays = array
276 .columns()
277 .iter()
278 .map(|a| take_impl(a.as_ref(), indices))
279 .collect::<Result<Vec<ArrayRef>, _>>()?;
280 let fields: Vec<(FieldRef, ArrayRef)> =
281 fields.iter().cloned().zip(arrays).collect();
282
283 let is_valid: Buffer = indices
285 .iter()
286 .map(|index| {
287 if let Some(index) = index {
288 array.is_valid(index.to_usize().unwrap())
289 } else {
290 false
291 }
292 })
293 .collect();
294
295 if fields.is_empty() {
296 let nulls = NullBuffer::new(BooleanBuffer::new(is_valid, 0, indices.len()));
297 Ok(Arc::new(StructArray::new_empty_fields(indices.len(), Some(nulls))))
298 } else {
299 Ok(Arc::new(StructArray::from((fields, is_valid))) as ArrayRef)
300 }
301 }
302 DataType::Dictionary(_, _) => downcast_dictionary_array! {
303 values => Ok(Arc::new(take_dict(values, indices)?)),
304 t => unimplemented!("Take not supported for dictionary type {:?}", t)
305 }
306 DataType::RunEndEncoded(_, _) => downcast_run_array! {
307 values => Ok(Arc::new(take_run(values, indices)?)),
308 t => unimplemented!("Take not supported for run type {:?}", t)
309 }
310 DataType::Binary => {
311 Ok(Arc::new(take_bytes(values.as_binary::<i32>(), indices)?))
312 }
313 DataType::LargeBinary => {
314 Ok(Arc::new(take_bytes(values.as_binary::<i64>(), indices)?))
315 }
316 DataType::BinaryView => {
317 Ok(Arc::new(take_byte_view(values.as_binary_view(), indices)?))
318 }
319 DataType::FixedSizeBinary(size) => {
320 let values = values
321 .as_any()
322 .downcast_ref::<FixedSizeBinaryArray>()
323 .unwrap();
324 Ok(Arc::new(take_fixed_size_binary(values, indices, *size)?))
325 }
326 DataType::Null => {
327 if values.len() >= indices.len() {
329 Ok(values.slice(0, indices.len()))
332 } else {
333 Ok(new_null_array(&DataType::Null, indices.len()))
335 }
336 }
337 DataType::Union(fields, UnionMode::Sparse) => {
338 let mut children = Vec::with_capacity(fields.len());
339 let values = values.as_any().downcast_ref::<UnionArray>().unwrap();
340 let type_ids = take_native(values.type_ids(), indices);
341 for (type_id, _field) in fields.iter() {
342 let values = values.child(type_id);
343 let values = take_impl(values, indices)?;
344 children.push(values);
345 }
346 let array = UnionArray::try_new(fields.clone(), type_ids, None, children)?;
347 Ok(Arc::new(array))
348 }
349 DataType::Union(fields, UnionMode::Dense) => {
350 let values = values.as_any().downcast_ref::<UnionArray>().unwrap();
351
352 let type_ids = <PrimitiveArray<Int8Type>>::try_new(take_native(values.type_ids(), indices), None)?;
353 let offsets = <PrimitiveArray<Int32Type>>::try_new(take_native(values.offsets().unwrap(), indices), None)?;
354
355 let children = fields.iter()
356 .map(|(field_type_id, _)| {
357 let mask = BooleanArray::from_unary(&type_ids, |value_type_id| value_type_id == field_type_id);
358
359 let indices = crate::filter::filter(&offsets, &mask)?;
360
361 let values = values.child(field_type_id);
362
363 take_impl(values, indices.as_primitive::<Int32Type>())
364 })
365 .collect::<Result<_, _>>()?;
366
367 let mut child_offsets = [0; 128];
368
369 let offsets = type_ids.values()
370 .iter()
371 .map(|&i| {
372 let offset = child_offsets[i as usize];
373
374 child_offsets[i as usize] += 1;
375
376 offset
377 })
378 .collect();
379
380 let (_, type_ids, _) = type_ids.into_parts();
381
382 let array = UnionArray::try_new(fields.clone(), type_ids, Some(offsets), children)?;
383
384 Ok(Arc::new(array))
385 }
386 t => unimplemented!("Take not supported for data type {:?}", t)
387 }
388}
389
390#[derive(Clone, Debug, Default)]
392pub struct TakeOptions {
393 pub check_bounds: bool,
397}
398
399fn take_primitive<T, I>(
409 values: &PrimitiveArray<T>,
410 indices: &PrimitiveArray<I>,
411) -> Result<PrimitiveArray<T>, ArrowError>
412where
413 T: ArrowPrimitiveType,
414 I: ArrowPrimitiveType,
415{
416 let values_buf = take_native(values.values(), indices);
417 let nulls = take_nulls(values.nulls(), indices);
418 Ok(PrimitiveArray::try_new(values_buf, nulls)?.with_data_type(values.data_type().clone()))
419}
420
421#[inline(never)]
422fn take_nulls<I: ArrowPrimitiveType>(
423 values: Option<&NullBuffer>,
424 indices: &PrimitiveArray<I>,
425) -> Option<NullBuffer> {
426 match values.filter(|n| n.null_count() > 0) {
427 Some(n) => NullBuffer::from_unsliced_buffer(
428 take_bits(n.inner(), indices).into_inner(),
429 indices.len(),
430 ),
431 None => indices.nulls().cloned(),
432 }
433}
434
435#[inline(never)]
436fn take_native<T: ArrowNativeType, I: ArrowPrimitiveType>(
437 values: &[T],
438 indices: &PrimitiveArray<I>,
439) -> ScalarBuffer<T> {
440 match indices.nulls().filter(|n| n.null_count() > 0) {
441 Some(n) => indices
442 .values()
443 .iter()
444 .enumerate()
445 .map(|(idx, index)| match values.get(index.as_usize()) {
446 Some(v) => *v,
447 None => match unsafe { n.inner().value_unchecked(idx) } {
449 false => T::default(),
450 true => panic!("Out-of-bounds index {index:?}"),
451 },
452 })
453 .collect(),
454 None => indices
455 .values()
456 .iter()
457 .map(|index| values[index.as_usize()])
458 .collect(),
459 }
460}
461
462#[inline(never)]
463fn take_bits<I: ArrowPrimitiveType>(
464 values: &BooleanBuffer,
465 indices: &PrimitiveArray<I>,
466) -> BooleanBuffer {
467 let len = indices.len();
468
469 match indices.nulls().filter(|n| n.null_count() > 0) {
470 Some(nulls) => {
471 let mut output_buffer = MutableBuffer::new_null(len);
472 let output_slice = output_buffer.as_slice_mut();
473 nulls.valid_indices().for_each(|idx| {
474 if values.value(unsafe { indices.value_unchecked(idx).as_usize() }) {
476 unsafe { bit_util::set_bit_raw(output_slice.as_mut_ptr(), idx) };
478 }
479 });
480 BooleanBuffer::new(output_buffer.into(), 0, len)
481 }
482 None => {
483 BooleanBuffer::collect_bool(len, |idx: usize| {
484 values.value(unsafe { indices.value_unchecked(idx).as_usize() })
486 })
487 }
488 }
489}
490
491fn take_boolean<IndexType: ArrowPrimitiveType>(
493 values: &BooleanArray,
494 indices: &PrimitiveArray<IndexType>,
495) -> BooleanArray {
496 let val_buf = take_bits(values.values(), indices);
497 let null_buf = take_nulls(values.nulls(), indices);
498 BooleanArray::new(val_buf, null_buf)
499}
500
501fn take_bytes<T: ByteArrayType, IndexType: ArrowPrimitiveType>(
503 array: &GenericByteArray<T>,
504 indices: &PrimitiveArray<IndexType>,
505) -> Result<GenericByteArray<T>, ArrowError> {
506 let mut values: Vec<u8> = Vec::new();
507 let mut offsets = Vec::with_capacity(indices.len() + 1);
508 offsets.push(T::Offset::default());
509
510 let input_offsets = array.value_offsets();
511 let mut capacity = 0;
512 let nulls = take_nulls(array.nulls(), indices);
513
514 match nulls.as_ref().filter(|n| n.null_count() > 0) {
516 None => {
518 for index in indices.values() {
519 let index = index.as_usize();
520 let start = input_offsets[index].as_usize();
521 let end = input_offsets[index + 1].as_usize();
522 capacity += end - start;
523 offsets.push(
524 T::Offset::from_usize(capacity)
525 .ok_or_else(|| ArrowError::OffsetOverflowError(capacity))?,
526 );
527 }
528
529 values.reserve(capacity);
530
531 let dst = values.spare_capacity_mut();
532 debug_assert!(dst.len() >= capacity);
533 let mut offset = 0;
534
535 for index in indices.values() {
536 unsafe {
539 let data: &[u8] = array.value_unchecked(index.as_usize()).as_ref();
540 std::ptr::copy_nonoverlapping(
541 data.as_ptr(),
542 dst.get_unchecked_mut(offset..).as_mut_ptr().cast::<u8>(),
543 data.len(),
544 );
545 offset += data.len();
546 }
547 }
548
549 unsafe {
551 values.set_len(capacity);
552 }
553 }
554 Some(output_nulls) => {
556 let mut source_ranges = Vec::with_capacity(indices.len() - output_nulls.null_count());
557 let mut last_filled = 0;
558
559 offsets.resize(indices.len() + 1, T::Offset::default());
561
562 for i in output_nulls.valid_indices() {
564 let current_offset = T::Offset::from_usize(capacity)
565 .ok_or_else(|| ArrowError::OffsetOverflowError(capacity))?;
566 if last_filled < i {
568 offsets[last_filled + 1..=i].fill(current_offset);
569 }
570
571 let index = unsafe { indices.value_unchecked(i) }.as_usize();
573 let start = input_offsets[index].as_usize();
574 let end = input_offsets[index + 1].as_usize();
575 capacity += end - start;
576 offsets[i + 1] = T::Offset::from_usize(capacity)
577 .ok_or_else(|| ArrowError::OffsetOverflowError(capacity))?;
578
579 source_ranges.push((start, end));
580 last_filled = i + 1;
581 }
582
583 let final_offset = T::Offset::from_usize(capacity)
585 .ok_or_else(|| ArrowError::OffsetOverflowError(capacity))?;
586 offsets[last_filled + 1..].fill(final_offset);
587 values.reserve(capacity);
589 debug_assert_eq!(
590 source_ranges.iter().map(|(s, e)| e - s).sum::<usize>(),
591 capacity,
592 "capacity must equal total bytes across all ranges"
593 );
594
595 let src = array.value_data();
596 let src = src.as_ptr();
597 let dst = values.spare_capacity_mut();
598 debug_assert!(dst.len() >= capacity);
599
600 let mut offset = 0;
601
602 for (start, end) in source_ranges {
603 let value_len = end - start;
604 unsafe {
608 std::ptr::copy_nonoverlapping(
609 src.add(start),
610 dst.get_unchecked_mut(offset..).as_mut_ptr().cast::<u8>(),
611 value_len,
612 );
613 offset += value_len;
614 }
615 }
616 unsafe { values.set_len(capacity) };
619 }
620 };
621
622 let array = unsafe {
625 let offsets = OffsetBuffer::new_unchecked(offsets.into());
626 GenericByteArray::<T>::new_unchecked(offsets, values.into(), nulls)
627 };
628
629 Ok(array)
630}
631
632fn take_byte_view<T: ByteViewType, IndexType: ArrowPrimitiveType>(
634 array: &GenericByteViewArray<T>,
635 indices: &PrimitiveArray<IndexType>,
636) -> Result<GenericByteViewArray<T>, ArrowError> {
637 let new_views = take_native(array.views(), indices);
638 let new_nulls = take_nulls(array.nulls(), indices);
639 Ok(unsafe {
641 GenericByteViewArray::new_unchecked(new_views, array.data_buffers().to_vec(), new_nulls)
642 })
643}
644
645fn take_list<IndexType, OffsetType>(
650 values: &GenericListArray<OffsetType::Native>,
651 indices: &PrimitiveArray<IndexType>,
652) -> Result<GenericListArray<OffsetType::Native>, ArrowError>
653where
654 IndexType: ArrowPrimitiveType,
655 OffsetType: ArrowPrimitiveType,
656 OffsetType::Native: OffsetSizeTrait,
657 PrimitiveArray<OffsetType>: From<Vec<OffsetType::Native>>,
658{
659 let list_offsets = values.value_offsets();
660 let child_data = values.values().to_data();
661 let nulls = take_nulls(values.nulls(), indices);
662
663 let mut new_offsets = Vec::with_capacity(indices.len() + 1);
664 new_offsets.push(OffsetType::Native::zero());
665
666 let use_nulls = child_data.null_count() > 0;
667
668 let capacity = child_data
669 .len()
670 .checked_div(values.len())
671 .map(|v| v * indices.len())
672 .unwrap_or_default();
673
674 let mut array_data = MutableArrayData::new(vec![&child_data], use_nulls, capacity);
675
676 match nulls.as_ref().filter(|n| n.null_count() > 0) {
677 None => {
678 for index in indices.values() {
679 let ix = index.as_usize();
680 let start = list_offsets[ix].as_usize();
681 let end = list_offsets[ix + 1].as_usize();
682 array_data.try_extend(0, start, end)?;
683 new_offsets.push(OffsetType::Native::from_usize(array_data.len()).unwrap());
684 }
685 }
686 Some(output_nulls) => {
687 assert_eq!(output_nulls.len(), indices.len());
688
689 let mut last_filled = 0;
690 for i in output_nulls.valid_indices() {
691 let current = OffsetType::Native::from_usize(array_data.len()).unwrap();
692 if last_filled < i {
694 new_offsets.extend(std::iter::repeat_n(current, i - last_filled));
695 }
696
697 let ix = unsafe { indices.value_unchecked(i) }.as_usize();
699 let start = list_offsets[ix].as_usize();
700 let end = list_offsets[ix + 1].as_usize();
701 array_data.try_extend(0, start, end)?;
702 new_offsets.push(OffsetType::Native::from_usize(array_data.len()).unwrap());
703 last_filled = i + 1;
704 }
705
706 let final_offset = OffsetType::Native::from_usize(array_data.len()).unwrap();
708 new_offsets.extend(std::iter::repeat_n(
709 final_offset,
710 indices.len() - last_filled,
711 ));
712 }
713 };
714
715 assert_eq!(
716 new_offsets.len(),
717 indices.len() + 1,
718 "New offsets was filled under/over the expected capacity"
719 );
720
721 let field = match values.data_type() {
722 DataType::List(field) | DataType::LargeList(field) => field.clone(),
723 d => unreachable!("take_list called with non-list data type {d}"),
724 };
725 let offsets = unsafe { OffsetBuffer::new_unchecked(ScalarBuffer::from(new_offsets)) };
727 let child = make_array(array_data.freeze());
728
729 GenericListArray::<OffsetType::Native>::try_new(field, offsets, child, nulls)
730}
731
732fn take_list_view<IndexType, OffsetType>(
733 values: &GenericListViewArray<OffsetType::Native>,
734 indices: &PrimitiveArray<IndexType>,
735) -> Result<GenericListViewArray<OffsetType::Native>, ArrowError>
736where
737 IndexType: ArrowPrimitiveType,
738 OffsetType: ArrowPrimitiveType,
739 OffsetType::Native: OffsetSizeTrait,
740{
741 let taken_offsets = take_native(values.offsets(), indices);
742 let taken_sizes = take_native(values.sizes(), indices);
743 let nulls = take_nulls(values.nulls(), indices);
744
745 let field = match values.data_type() {
746 DataType::ListView(field) | DataType::LargeListView(field) => field.clone(),
747 d => unreachable!("take_list_view called with non-list-view data type {d}"),
748 };
749
750 Ok(unsafe {
753 GenericListViewArray::<OffsetType::Native>::new_unchecked(
754 field,
755 taken_offsets,
756 taken_sizes,
757 Arc::clone(values.values()),
758 nulls,
759 )
760 })
761}
762
763fn take_fixed_size_list<IndexType: ArrowPrimitiveType>(
769 values: &FixedSizeListArray,
770 indices: &PrimitiveArray<IndexType>,
771 length: <UInt32Type as ArrowPrimitiveType>::Native,
772) -> Result<FixedSizeListArray, ArrowError> {
773 let list_indices = take_value_indices_from_fixed_size_list(values, indices, length)?;
774 let taken = take_impl::<UInt32Type>(values.values().as_ref(), &list_indices)?;
775
776 let num_bytes = bit_util::ceil(indices.len(), 8);
778 let mut null_buf = MutableBuffer::new(num_bytes).with_bitset(num_bytes, true);
779 let null_slice = null_buf.as_slice_mut();
780
781 for i in 0..indices.len() {
782 let index = indices
783 .value(i)
784 .to_usize()
785 .ok_or_else(|| ArrowError::ComputeError("Cast to usize failed".to_string()))?;
786 if !indices.is_valid(i) || values.is_null(index) {
787 bit_util::unset_bit(null_slice, i);
788 }
789 }
790
791 let field = match values.data_type() {
792 DataType::FixedSizeList(field, _) => field.clone(),
793 d => unreachable!("take_fixed_size_list called with non-fixed-size-list data type {d}"),
794 };
795 let nulls = NullBuffer::from_unsliced_buffer(null_buf, indices.len());
796
797 FixedSizeListArray::try_new(field, length as i32, taken, nulls)
798}
799
800fn take_fixed_size_binary<IndexType: ArrowPrimitiveType>(
806 values: &FixedSizeBinaryArray,
807 indices: &PrimitiveArray<IndexType>,
808 size: i32,
809) -> Result<FixedSizeBinaryArray, ArrowError> {
810 let size_usize = usize::try_from(size).map_err(|_| {
811 ArrowError::InvalidArgumentError(format!("Cannot convert size '{}' to usize", size))
812 })?;
813
814 let result_buffer = match size_usize {
815 1 => take_fixed_size::<IndexType, 1>(values.values(), indices),
816 2 => take_fixed_size::<IndexType, 2>(values.values(), indices),
817 4 => take_fixed_size::<IndexType, 4>(values.values(), indices),
818 8 => take_fixed_size::<IndexType, 8>(values.values(), indices),
819 16 => take_fixed_size::<IndexType, 16>(values.values(), indices),
820 _ => take_fixed_size_binary_buffer_dynamic_length(values, indices, size_usize),
821 };
822
823 let value_nulls = take_nulls(values.nulls(), indices);
824 let final_nulls = NullBuffer::union(value_nulls.as_ref(), indices.nulls());
825
826 return FixedSizeBinaryArray::try_new(size, result_buffer, final_nulls);
827
828 #[inline(never)]
830 fn take_fixed_size_binary_buffer_dynamic_length<IndexType: ArrowPrimitiveType>(
831 values: &FixedSizeBinaryArray,
832 indices: &PrimitiveArray<IndexType>,
833 size_usize: usize,
834 ) -> Buffer {
835 let values_buffer = values.values().as_slice();
836 let mut values_buffer_builder = BufferBuilder::new(indices.len() * size_usize);
837
838 if indices.null_count() == 0 {
839 let array_iter = indices.values().iter().map(|idx| {
840 let offset = idx.as_usize() * size_usize;
841 &values_buffer[offset..offset + size_usize]
842 });
843 for slice in array_iter {
844 values_buffer_builder.append_slice(slice);
845 }
846 } else {
847 let array_iter = indices.iter().map(|idx| {
850 idx.map(|idx| {
851 let offset = idx.as_usize() * size_usize;
852 &values_buffer[offset..offset + size_usize]
853 })
854 });
855 for slice in array_iter {
856 match slice {
857 None => values_buffer_builder.append_n(size_usize, 0),
858 Some(slice) => values_buffer_builder.append_slice(slice),
859 }
860 }
861 }
862
863 values_buffer_builder.finish()
864 }
865}
866
867fn take_fixed_size<IndexType: ArrowPrimitiveType, const N: usize>(
880 buffer: &Buffer,
881 indices: &PrimitiveArray<IndexType>,
882) -> Buffer {
883 assert_eq!(
884 buffer.len() % N,
885 0,
886 "Invalid array length in take_fixed_size"
887 );
888
889 let ptr = buffer.as_ptr();
890 let chunk_ptr = ptr.cast::<[u8; N]>();
891 let chunk_len = buffer.len() / N;
892 let buffer: &[[u8; N]] = unsafe {
893 std::slice::from_raw_parts(chunk_ptr, chunk_len)
896 };
897
898 let result_buffer = match indices.nulls().filter(|n| n.null_count() > 0) {
899 Some(n) => indices
900 .values()
901 .iter()
902 .enumerate()
903 .map(|(idx, index)| match buffer.get(index.as_usize()) {
904 Some(v) => *v,
905 None => match unsafe { n.inner().value_unchecked(idx) } {
907 false => [0u8; N],
908 true => panic!("Out-of-bounds index {index:?}"),
909 },
910 })
911 .collect::<Vec<_>>(),
912 None => indices
913 .values()
914 .iter()
915 .map(|index| buffer[index.as_usize()])
916 .collect::<Vec<_>>(),
917 };
918
919 let mut vec = ManuallyDrop::new(result_buffer); let ptr = vec.as_mut_ptr();
921 let len = vec.len();
922 let cap = vec.capacity();
923 let result_buffer = unsafe {
924 Vec::from_raw_parts(ptr.cast::<u8>(), len * N, cap * N)
926 };
927
928 Buffer::from_vec(result_buffer)
929}
930
931fn take_dict<T: ArrowDictionaryKeyType, I: ArrowPrimitiveType>(
936 values: &DictionaryArray<T>,
937 indices: &PrimitiveArray<I>,
938) -> Result<DictionaryArray<T>, ArrowError> {
939 let new_keys = take_primitive(values.keys(), indices)?;
940 Ok(unsafe { DictionaryArray::new_unchecked(new_keys, values.values().clone()) })
941}
942
943fn take_run<T: RunEndIndexType, I: ArrowPrimitiveType>(
952 run_array: &RunArray<T>,
953 logical_indices: &PrimitiveArray<I>,
954) -> Result<RunArray<T>, ArrowError> {
955 let physical_indices = run_array.get_physical_indices(logical_indices.values())?;
957
958 let mut new_run_ends_builder = BufferBuilder::<T::Native>::new(1);
962 let mut take_value_indices = BufferBuilder::<I::Native>::new(1);
963
964 let values_cmp = make_comparator(
965 run_array.values().as_ref(),
966 run_array.values().as_ref(),
967 SortOptions::default(),
968 )?;
969
970 for ix in 1..physical_indices.len() {
971 let prev_idx = physical_indices[ix - 1];
972 let cur_idx = physical_indices[ix];
973 let is_new_run = cur_idx != prev_idx && values_cmp(cur_idx, prev_idx).is_ne();
974 if is_new_run {
975 take_value_indices.append(I::Native::from_usize(prev_idx).unwrap());
976 new_run_ends_builder.append(T::Native::from_usize(ix).unwrap());
977 }
978 }
979 take_value_indices
980 .append(I::Native::from_usize(physical_indices[physical_indices.len() - 1]).unwrap());
981 new_run_ends_builder.append(T::Native::from_usize(physical_indices.len()).unwrap());
982
983 let run_ends = unsafe {
985 RunEndBuffer::new_unchecked(
986 ScalarBuffer::from(new_run_ends_builder.finish()),
987 0,
988 physical_indices.len(),
989 )
990 };
991
992 let take_value_indices =
993 PrimitiveArray::<I>::new(ScalarBuffer::from(take_value_indices.finish()), None);
994
995 let new_values = take(run_array.values(), &take_value_indices, None)?;
996
997 Ok(
999 unsafe {
1000 RunArray::<T>::new_unchecked(run_array.data_type().clone(), run_ends, new_values)
1001 },
1002 )
1003}
1004
1005fn take_value_indices_from_fixed_size_list<IndexType>(
1007 list: &FixedSizeListArray,
1008 indices: &PrimitiveArray<IndexType>,
1009 length: <UInt32Type as ArrowPrimitiveType>::Native,
1010) -> Result<PrimitiveArray<UInt32Type>, ArrowError>
1011where
1012 IndexType: ArrowPrimitiveType,
1013{
1014 let mut values = UInt32Builder::with_capacity(length as usize * indices.len());
1015
1016 for i in 0..indices.len() {
1017 if indices.is_valid(i) {
1018 let index = indices
1019 .value(i)
1020 .to_usize()
1021 .ok_or_else(|| ArrowError::ComputeError("Cast to usize failed".to_string()))?;
1022 let start = list.value_offset(index) as <UInt32Type as ArrowPrimitiveType>::Native;
1023
1024 unsafe {
1026 values.append_trusted_len_iter(start..start + length);
1027 }
1028 } else {
1029 values.append_nulls(length as usize);
1030 }
1031 }
1032
1033 Ok(values.finish())
1034}
1035
1036trait ToIndices {
1039 type T: ArrowPrimitiveType;
1040
1041 fn to_indices(&self) -> PrimitiveArray<Self::T>;
1042}
1043
1044macro_rules! to_indices_reinterpret {
1045 ($t:ty, $o:ty) => {
1046 impl ToIndices for PrimitiveArray<$t> {
1047 type T = $o;
1048
1049 fn to_indices(&self) -> PrimitiveArray<$o> {
1050 let cast = ScalarBuffer::new(self.values().inner().clone(), 0, self.len());
1051 PrimitiveArray::new(cast, self.nulls().cloned())
1052 }
1053 }
1054 };
1055}
1056
1057macro_rules! to_indices_identity {
1058 ($t:ty) => {
1059 impl ToIndices for PrimitiveArray<$t> {
1060 type T = $t;
1061
1062 fn to_indices(&self) -> PrimitiveArray<$t> {
1063 self.clone()
1064 }
1065 }
1066 };
1067}
1068
1069macro_rules! to_indices_widening {
1070 ($t:ty, $o:ty) => {
1071 impl ToIndices for PrimitiveArray<$t> {
1072 type T = UInt32Type;
1073
1074 fn to_indices(&self) -> PrimitiveArray<$o> {
1075 let cast = self.values().iter().copied().map(|x| x as _).collect();
1076 PrimitiveArray::new(cast, self.nulls().cloned())
1077 }
1078 }
1079 };
1080}
1081
1082to_indices_widening!(UInt8Type, UInt32Type);
1083to_indices_widening!(Int8Type, UInt32Type);
1084
1085to_indices_widening!(UInt16Type, UInt32Type);
1086to_indices_widening!(Int16Type, UInt32Type);
1087
1088to_indices_identity!(UInt32Type);
1089to_indices_reinterpret!(Int32Type, UInt32Type);
1090
1091to_indices_identity!(UInt64Type);
1092to_indices_reinterpret!(Int64Type, UInt64Type);
1093
1094pub fn take_record_batch(
1133 record_batch: &RecordBatch,
1134 indices: &dyn Array,
1135) -> Result<RecordBatch, ArrowError> {
1136 let columns = record_batch
1137 .columns()
1138 .iter()
1139 .map(|c| take(c, indices, None))
1140 .collect::<Result<Vec<_>, _>>()?;
1141 RecordBatch::try_new(record_batch.schema(), columns)
1142}
1143
1144#[cfg(test)]
1145mod tests {
1146 use super::*;
1147 use arrow_array::builder::*;
1148 use arrow_buffer::{IntervalDayTime, IntervalMonthDayNano};
1149 use arrow_data::ArrayData;
1150 use arrow_schema::{Field, Fields, TimeUnit, UnionFields};
1151 use num_traits::ToPrimitive;
1152
1153 fn test_take_decimal_arrays(
1154 data: Vec<Option<i128>>,
1155 index: &UInt32Array,
1156 options: Option<TakeOptions>,
1157 expected_data: Vec<Option<i128>>,
1158 precision: &u8,
1159 scale: &i8,
1160 ) -> Result<(), ArrowError> {
1161 let output = data
1162 .into_iter()
1163 .collect::<Decimal128Array>()
1164 .with_precision_and_scale(*precision, *scale)
1165 .unwrap();
1166
1167 let expected = expected_data
1168 .into_iter()
1169 .collect::<Decimal128Array>()
1170 .with_precision_and_scale(*precision, *scale)
1171 .unwrap();
1172
1173 let expected = Arc::new(expected) as ArrayRef;
1174 let output = take(&output, index, options).unwrap();
1175 assert_eq!(&output, &expected);
1176 Ok(())
1177 }
1178
1179 fn test_take_boolean_arrays(
1180 data: Vec<Option<bool>>,
1181 index: &UInt32Array,
1182 options: Option<TakeOptions>,
1183 expected_data: Vec<Option<bool>>,
1184 ) {
1185 let output = BooleanArray::from(data);
1186 let expected = Arc::new(BooleanArray::from(expected_data)) as ArrayRef;
1187 let output = take(&output, index, options).unwrap();
1188 assert_eq!(&output, &expected)
1189 }
1190
1191 fn test_take_primitive_arrays<T>(
1192 data: Vec<Option<T::Native>>,
1193 index: &UInt32Array,
1194 options: Option<TakeOptions>,
1195 expected_data: Vec<Option<T::Native>>,
1196 ) -> Result<(), ArrowError>
1197 where
1198 T: ArrowPrimitiveType,
1199 PrimitiveArray<T>: From<Vec<Option<T::Native>>>,
1200 {
1201 let output = PrimitiveArray::<T>::from(data);
1202 let expected = Arc::new(PrimitiveArray::<T>::from(expected_data)) as ArrayRef;
1203 let output = take(&output, index, options)?;
1204 assert_eq!(&output, &expected);
1205 Ok(())
1206 }
1207
1208 fn test_take_primitive_arrays_non_null<T>(
1209 data: Vec<T::Native>,
1210 index: &UInt32Array,
1211 options: Option<TakeOptions>,
1212 expected_data: Vec<Option<T::Native>>,
1213 ) -> Result<(), ArrowError>
1214 where
1215 T: ArrowPrimitiveType,
1216 PrimitiveArray<T>: From<Vec<T::Native>>,
1217 PrimitiveArray<T>: From<Vec<Option<T::Native>>>,
1218 {
1219 let output = PrimitiveArray::<T>::from(data);
1220 let expected = Arc::new(PrimitiveArray::<T>::from(expected_data)) as ArrayRef;
1221 let output = take(&output, index, options)?;
1222 assert_eq!(&output, &expected);
1223 Ok(())
1224 }
1225
1226 fn test_take_impl_primitive_arrays<T, I>(
1227 data: Vec<Option<T::Native>>,
1228 index: &PrimitiveArray<I>,
1229 options: Option<TakeOptions>,
1230 expected_data: Vec<Option<T::Native>>,
1231 ) where
1232 T: ArrowPrimitiveType,
1233 PrimitiveArray<T>: From<Vec<Option<T::Native>>>,
1234 I: ArrowPrimitiveType,
1235 {
1236 let output = PrimitiveArray::<T>::from(data);
1237 let expected = PrimitiveArray::<T>::from(expected_data);
1238 let output = take(&output, index, options).unwrap();
1239 let output = output.as_any().downcast_ref::<PrimitiveArray<T>>().unwrap();
1240 assert_eq!(output, &expected)
1241 }
1242
1243 fn create_test_struct(values: Vec<Option<(Option<bool>, Option<i32>)>>) -> StructArray {
1245 let mut struct_builder = StructBuilder::new(
1246 Fields::from(vec![
1247 Field::new("a", DataType::Boolean, true),
1248 Field::new("b", DataType::Int32, true),
1249 ]),
1250 vec![
1251 Box::new(BooleanBuilder::with_capacity(values.len())),
1252 Box::new(Int32Builder::with_capacity(values.len())),
1253 ],
1254 );
1255
1256 for value in values {
1257 struct_builder
1258 .field_builder::<BooleanBuilder>(0)
1259 .unwrap()
1260 .append_option(value.and_then(|v| v.0));
1261 struct_builder
1262 .field_builder::<Int32Builder>(1)
1263 .unwrap()
1264 .append_option(value.and_then(|v| v.1));
1265 struct_builder.append(value.is_some());
1266 }
1267 struct_builder.finish()
1268 }
1269
1270 #[test]
1271 fn test_take_decimal128_non_null_indices() {
1272 let index = UInt32Array::from(vec![0, 5, 3, 1, 4, 2]);
1273 let precision: u8 = 10;
1274 let scale: i8 = 5;
1275 test_take_decimal_arrays(
1276 vec![None, Some(3), Some(5), Some(2), Some(3), None],
1277 &index,
1278 None,
1279 vec![None, None, Some(2), Some(3), Some(3), Some(5)],
1280 &precision,
1281 &scale,
1282 )
1283 .unwrap();
1284 }
1285
1286 #[test]
1287 fn test_take_decimal128() {
1288 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(3), Some(2)]);
1289 let precision: u8 = 10;
1290 let scale: i8 = 5;
1291 test_take_decimal_arrays(
1292 vec![Some(0), Some(1), Some(2), Some(3), Some(4)],
1293 &index,
1294 None,
1295 vec![Some(3), None, Some(1), Some(3), Some(2)],
1296 &precision,
1297 &scale,
1298 )
1299 .unwrap();
1300 }
1301
1302 #[test]
1303 fn test_take_primitive_non_null_indices() {
1304 let index = UInt32Array::from(vec![0, 5, 3, 1, 4, 2]);
1305 test_take_primitive_arrays::<Int8Type>(
1306 vec![None, Some(3), Some(5), Some(2), Some(3), None],
1307 &index,
1308 None,
1309 vec![None, None, Some(2), Some(3), Some(3), Some(5)],
1310 )
1311 .unwrap();
1312 }
1313
1314 #[test]
1315 fn test_take_primitive_non_null_values() {
1316 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(3), Some(2)]);
1317 test_take_primitive_arrays::<Int8Type>(
1318 vec![Some(0), Some(1), Some(2), Some(3), Some(4)],
1319 &index,
1320 None,
1321 vec![Some(3), None, Some(1), Some(3), Some(2)],
1322 )
1323 .unwrap();
1324 }
1325
1326 #[test]
1327 fn test_take_primitive_non_null() {
1328 let index = UInt32Array::from(vec![0, 5, 3, 1, 4, 2]);
1329 test_take_primitive_arrays::<Int8Type>(
1330 vec![Some(0), Some(3), Some(5), Some(2), Some(3), Some(1)],
1331 &index,
1332 None,
1333 vec![Some(0), Some(1), Some(2), Some(3), Some(3), Some(5)],
1334 )
1335 .unwrap();
1336 }
1337
1338 #[test]
1339 fn test_take_primitive_nullable_indices_non_null_values_with_offset() {
1340 let index = UInt32Array::from(vec![Some(0), Some(1), Some(2), Some(3), None, None]);
1341 let index = index.slice(2, 4);
1342 let index = index.as_any().downcast_ref::<UInt32Array>().unwrap();
1343
1344 assert_eq!(
1345 index,
1346 &UInt32Array::from(vec![Some(2), Some(3), None, None])
1347 );
1348
1349 test_take_primitive_arrays_non_null::<Int64Type>(
1350 vec![0, 10, 20, 30, 40, 50],
1351 index,
1352 None,
1353 vec![Some(20), Some(30), None, None],
1354 )
1355 .unwrap();
1356 }
1357
1358 #[test]
1359 fn test_take_primitive_nullable_indices_nullable_values_with_offset() {
1360 let index = UInt32Array::from(vec![Some(0), Some(1), Some(2), Some(3), None, None]);
1361 let index = index.slice(2, 4);
1362 let index = index.as_any().downcast_ref::<UInt32Array>().unwrap();
1363
1364 assert_eq!(
1365 index,
1366 &UInt32Array::from(vec![Some(2), Some(3), None, None])
1367 );
1368
1369 test_take_primitive_arrays::<Int64Type>(
1370 vec![None, None, Some(20), Some(30), Some(40), Some(50)],
1371 index,
1372 None,
1373 vec![Some(20), Some(30), None, None],
1374 )
1375 .unwrap();
1376 }
1377
1378 #[test]
1379 fn test_take_primitive() {
1380 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(3), Some(2)]);
1381
1382 test_take_primitive_arrays::<Int8Type>(
1384 vec![Some(0), None, Some(2), Some(3), None],
1385 &index,
1386 None,
1387 vec![Some(3), None, None, Some(3), Some(2)],
1388 )
1389 .unwrap();
1390
1391 test_take_primitive_arrays::<Int16Type>(
1393 vec![Some(0), None, Some(2), Some(3), None],
1394 &index,
1395 None,
1396 vec![Some(3), None, None, Some(3), Some(2)],
1397 )
1398 .unwrap();
1399
1400 test_take_primitive_arrays::<Int32Type>(
1402 vec![Some(0), None, Some(2), Some(3), None],
1403 &index,
1404 None,
1405 vec![Some(3), None, None, Some(3), Some(2)],
1406 )
1407 .unwrap();
1408
1409 test_take_primitive_arrays::<Int64Type>(
1411 vec![Some(0), None, Some(2), Some(3), None],
1412 &index,
1413 None,
1414 vec![Some(3), None, None, Some(3), Some(2)],
1415 )
1416 .unwrap();
1417
1418 test_take_primitive_arrays::<UInt8Type>(
1420 vec![Some(0), None, Some(2), Some(3), None],
1421 &index,
1422 None,
1423 vec![Some(3), None, None, Some(3), Some(2)],
1424 )
1425 .unwrap();
1426
1427 test_take_primitive_arrays::<UInt16Type>(
1429 vec![Some(0), None, Some(2), Some(3), None],
1430 &index,
1431 None,
1432 vec![Some(3), None, None, Some(3), Some(2)],
1433 )
1434 .unwrap();
1435
1436 test_take_primitive_arrays::<UInt32Type>(
1438 vec![Some(0), None, Some(2), Some(3), None],
1439 &index,
1440 None,
1441 vec![Some(3), None, None, Some(3), Some(2)],
1442 )
1443 .unwrap();
1444
1445 test_take_primitive_arrays::<Int64Type>(
1447 vec![Some(0), None, Some(2), Some(-15), None],
1448 &index,
1449 None,
1450 vec![Some(-15), None, None, Some(-15), Some(2)],
1451 )
1452 .unwrap();
1453
1454 test_take_primitive_arrays::<IntervalYearMonthType>(
1456 vec![Some(0), None, Some(2), Some(-15), None],
1457 &index,
1458 None,
1459 vec![Some(-15), None, None, Some(-15), Some(2)],
1460 )
1461 .unwrap();
1462
1463 let v1 = IntervalDayTime::new(0, 0);
1465 let v2 = IntervalDayTime::new(2, 0);
1466 let v3 = IntervalDayTime::new(-15, 0);
1467 test_take_primitive_arrays::<IntervalDayTimeType>(
1468 vec![Some(v1), None, Some(v2), Some(v3), None],
1469 &index,
1470 None,
1471 vec![Some(v3), None, None, Some(v3), Some(v2)],
1472 )
1473 .unwrap();
1474
1475 let v1 = IntervalMonthDayNano::new(0, 0, 0);
1477 let v2 = IntervalMonthDayNano::new(2, 0, 0);
1478 let v3 = IntervalMonthDayNano::new(-15, 0, 0);
1479 test_take_primitive_arrays::<IntervalMonthDayNanoType>(
1480 vec![Some(v1), None, Some(v2), Some(v3), None],
1481 &index,
1482 None,
1483 vec![Some(v3), None, None, Some(v3), Some(v2)],
1484 )
1485 .unwrap();
1486
1487 test_take_primitive_arrays::<DurationSecondType>(
1489 vec![Some(0), None, Some(2), Some(-15), None],
1490 &index,
1491 None,
1492 vec![Some(-15), None, None, Some(-15), Some(2)],
1493 )
1494 .unwrap();
1495
1496 test_take_primitive_arrays::<DurationMillisecondType>(
1498 vec![Some(0), None, Some(2), Some(-15), None],
1499 &index,
1500 None,
1501 vec![Some(-15), None, None, Some(-15), Some(2)],
1502 )
1503 .unwrap();
1504
1505 test_take_primitive_arrays::<DurationMicrosecondType>(
1507 vec![Some(0), None, Some(2), Some(-15), None],
1508 &index,
1509 None,
1510 vec![Some(-15), None, None, Some(-15), Some(2)],
1511 )
1512 .unwrap();
1513
1514 test_take_primitive_arrays::<DurationNanosecondType>(
1516 vec![Some(0), None, Some(2), Some(-15), None],
1517 &index,
1518 None,
1519 vec![Some(-15), None, None, Some(-15), Some(2)],
1520 )
1521 .unwrap();
1522
1523 test_take_primitive_arrays::<Float32Type>(
1525 vec![Some(0.0), None, Some(2.21), Some(-3.1), None],
1526 &index,
1527 None,
1528 vec![Some(-3.1), None, None, Some(-3.1), Some(2.21)],
1529 )
1530 .unwrap();
1531
1532 test_take_primitive_arrays::<Float64Type>(
1534 vec![Some(0.0), None, Some(2.21), Some(-3.1), None],
1535 &index,
1536 None,
1537 vec![Some(-3.1), None, None, Some(-3.1), Some(2.21)],
1538 )
1539 .unwrap();
1540 }
1541
1542 #[test]
1543 fn test_take_preserve_timezone() {
1544 let index = Int64Array::from(vec![Some(0), None]);
1545
1546 let input = TimestampNanosecondArray::from(vec![
1547 1_639_715_368_000_000_000,
1548 1_639_715_368_000_000_000,
1549 ])
1550 .with_timezone("UTC".to_string());
1551 let result = take(&input, &index, None).unwrap();
1552 match result.data_type() {
1553 DataType::Timestamp(TimeUnit::Nanosecond, tz) => {
1554 assert_eq!(tz.clone(), Some("UTC".into()))
1555 }
1556 _ => panic!(),
1557 }
1558 }
1559
1560 #[test]
1561 fn test_take_impl_primitive_with_int64_indices() {
1562 let index = Int64Array::from(vec![Some(3), None, Some(1), Some(3), Some(2)]);
1563
1564 test_take_impl_primitive_arrays::<Int16Type, Int64Type>(
1566 vec![Some(0), None, Some(2), Some(3), None],
1567 &index,
1568 None,
1569 vec![Some(3), None, None, Some(3), Some(2)],
1570 );
1571
1572 test_take_impl_primitive_arrays::<Int64Type, Int64Type>(
1574 vec![Some(0), None, Some(2), Some(-15), None],
1575 &index,
1576 None,
1577 vec![Some(-15), None, None, Some(-15), Some(2)],
1578 );
1579
1580 test_take_impl_primitive_arrays::<UInt64Type, Int64Type>(
1582 vec![Some(0), None, Some(2), Some(3), None],
1583 &index,
1584 None,
1585 vec![Some(3), None, None, Some(3), Some(2)],
1586 );
1587
1588 test_take_impl_primitive_arrays::<DurationMillisecondType, Int64Type>(
1590 vec![Some(0), None, Some(2), Some(-15), None],
1591 &index,
1592 None,
1593 vec![Some(-15), None, None, Some(-15), Some(2)],
1594 );
1595
1596 test_take_impl_primitive_arrays::<Float32Type, Int64Type>(
1598 vec![Some(0.0), None, Some(2.21), Some(-3.1), None],
1599 &index,
1600 None,
1601 vec![Some(-3.1), None, None, Some(-3.1), Some(2.21)],
1602 );
1603 }
1604
1605 #[test]
1606 fn test_take_impl_primitive_with_uint8_indices() {
1607 let index = UInt8Array::from(vec![Some(3), None, Some(1), Some(3), Some(2)]);
1608
1609 test_take_impl_primitive_arrays::<Int16Type, UInt8Type>(
1611 vec![Some(0), None, Some(2), Some(3), None],
1612 &index,
1613 None,
1614 vec![Some(3), None, None, Some(3), Some(2)],
1615 );
1616
1617 test_take_impl_primitive_arrays::<DurationMillisecondType, UInt8Type>(
1619 vec![Some(0), None, Some(2), Some(-15), None],
1620 &index,
1621 None,
1622 vec![Some(-15), None, None, Some(-15), Some(2)],
1623 );
1624
1625 test_take_impl_primitive_arrays::<Float32Type, UInt8Type>(
1627 vec![Some(0.0), None, Some(2.21), Some(-3.1), None],
1628 &index,
1629 None,
1630 vec![Some(-3.1), None, None, Some(-3.1), Some(2.21)],
1631 );
1632 }
1633
1634 #[test]
1635 fn test_take_bool() {
1636 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(3), Some(2)]);
1637 test_take_boolean_arrays(
1639 vec![Some(false), None, Some(true), Some(false), None],
1640 &index,
1641 None,
1642 vec![Some(false), None, None, Some(false), Some(true)],
1643 );
1644 }
1645
1646 #[test]
1647 fn test_take_bool_nullable_index() {
1648 let index_data = ArrayData::try_new(
1650 DataType::UInt32,
1651 6,
1652 Some(Buffer::from_iter(vec![
1653 false, true, false, true, false, true,
1654 ])),
1655 0,
1656 vec![Buffer::from_iter(vec![99, 0, 999, 1, 9999, 2])],
1657 vec![],
1658 )
1659 .unwrap();
1660 let index = UInt32Array::from(index_data);
1661 test_take_boolean_arrays(
1662 vec![Some(true), None, Some(false)],
1663 &index,
1664 None,
1665 vec![None, Some(true), None, None, None, Some(false)],
1666 );
1667 }
1668
1669 #[test]
1670 fn test_take_bool_nullable_index_nonnull_values() {
1671 let index_data = ArrayData::try_new(
1673 DataType::UInt32,
1674 6,
1675 Some(Buffer::from_iter(vec![
1676 false, true, false, true, false, true,
1677 ])),
1678 0,
1679 vec![Buffer::from_iter(vec![99, 0, 999, 1, 9999, 2])],
1680 vec![],
1681 )
1682 .unwrap();
1683 let index = UInt32Array::from(index_data);
1684 test_take_boolean_arrays(
1685 vec![Some(true), Some(true), Some(false)],
1686 &index,
1687 None,
1688 vec![None, Some(true), None, Some(true), None, Some(false)],
1689 );
1690 }
1691
1692 #[test]
1693 fn test_take_bool_with_offset() {
1694 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(3), Some(2), None]);
1695 let index = index.slice(2, 4);
1696 let index = index
1697 .as_any()
1698 .downcast_ref::<PrimitiveArray<UInt32Type>>()
1699 .unwrap();
1700
1701 test_take_boolean_arrays(
1703 vec![Some(false), None, Some(true), Some(false), None],
1704 index,
1705 None,
1706 vec![None, Some(false), Some(true), None],
1707 );
1708 }
1709
1710 fn _test_take_string<'a, K>()
1711 where
1712 K: Array + PartialEq + From<Vec<Option<&'a str>>> + 'static,
1713 {
1714 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(3), Some(4)]);
1715
1716 let array = K::from(vec![
1717 Some("one"),
1718 None,
1719 Some("three"),
1720 Some("four"),
1721 Some("five"),
1722 ]);
1723 let actual = take(&array, &index, None).unwrap();
1724 assert_eq!(actual.len(), index.len());
1725
1726 let actual = actual.as_any().downcast_ref::<K>().unwrap();
1727
1728 let expected = K::from(vec![Some("four"), None, None, Some("four"), Some("five")]);
1729
1730 assert_eq!(actual, &expected);
1731 }
1732
1733 #[test]
1734 fn test_take_string() {
1735 _test_take_string::<StringArray>()
1736 }
1737
1738 #[test]
1739 fn test_take_large_string() {
1740 _test_take_string::<LargeStringArray>()
1741 }
1742
1743 #[test]
1744 fn test_take_slice_string() {
1745 let strings = StringArray::from(vec![Some("hello"), None, Some("world"), None, Some("hi")]);
1746 let indices = Int32Array::from(vec![Some(0), Some(1), None, Some(0), Some(2)]);
1747 let indices_slice = indices.slice(1, 4);
1748 let expected = StringArray::from(vec![None, None, Some("hello"), Some("world")]);
1749 let result = take(&strings, &indices_slice, None).unwrap();
1750 assert_eq!(result.as_ref(), &expected);
1751 }
1752
1753 #[test]
1758 fn test_take_bytes_sliced_values() {
1759 let values = StringArray::from(vec![
1760 Some("aaa"),
1761 Some("bbb"),
1762 None,
1763 Some("ccccc"),
1764 Some("dd"),
1765 None,
1766 Some("eeee"),
1767 ]);
1768 let sliced = values.slice(2, 5);
1771
1772 let indices = Int32Array::from(vec![1, 2, 4, 1]);
1775 let result = take(&sliced, &indices, None).unwrap();
1776 let expected =
1777 StringArray::from(vec![Some("ccccc"), Some("dd"), Some("eeee"), Some("ccccc")]);
1778 assert_eq!(result.as_string::<i32>(), &expected);
1779
1780 let indices = Int32Array::from(vec![Some(1), None, Some(0), Some(4), Some(3)]);
1783 let result = take(&sliced, &indices, None).unwrap();
1784 let expected = StringArray::from(vec![Some("ccccc"), None, None, Some("eeee"), None]);
1785 assert_eq!(result.as_string::<i32>(), &expected);
1786 }
1787
1788 fn _test_byte_view<T>()
1789 where
1790 T: ByteViewType,
1791 str: AsRef<T::Native>,
1792 T::Native: PartialEq,
1793 {
1794 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(3), Some(4), Some(2)]);
1795 let array = {
1796 let mut builder = GenericByteViewBuilder::<T>::new();
1798 builder.append_value("hello");
1799 builder.append_value("world");
1800 builder.append_null();
1801 builder.append_value("large payload over 12 bytes");
1802 builder.append_value("lulu");
1803 builder.finish()
1804 };
1805
1806 let actual = take(&array, &index, None).unwrap();
1807
1808 assert_eq!(actual.len(), index.len());
1809
1810 let expected = {
1811 let mut builder = GenericByteViewBuilder::<T>::new();
1813 builder.append_value("large payload over 12 bytes");
1814 builder.append_null();
1815 builder.append_value("world");
1816 builder.append_value("large payload over 12 bytes");
1817 builder.append_value("lulu");
1818 builder.append_null();
1819 builder.finish()
1820 };
1821
1822 assert_eq!(actual.as_ref(), &expected);
1823 }
1824
1825 #[test]
1826 fn test_take_string_view() {
1827 _test_byte_view::<StringViewType>()
1828 }
1829
1830 #[test]
1831 fn test_take_binary_view() {
1832 _test_byte_view::<BinaryViewType>()
1833 }
1834
1835 macro_rules! test_take_list {
1836 ($offset_type:ty, $list_data_type:ident, $list_array_type:ident) => {{
1837 let value_data = Int32Array::from(vec![0, 0, 0, -1, -2, -1, 2, 3]).into_data();
1839 let value_offsets: [$offset_type; 5] = [0, 3, 6, 6, 8];
1841 let value_offsets = Buffer::from_slice_ref(&value_offsets);
1842 let list_data_type =
1844 DataType::$list_data_type(Arc::new(Field::new_list_field(DataType::Int32, false)));
1845 let list_data = ArrayData::builder(list_data_type.clone())
1846 .len(4)
1847 .add_buffer(value_offsets)
1848 .add_child_data(value_data)
1849 .build()
1850 .unwrap();
1851 let list_array = $list_array_type::from(list_data);
1852
1853 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(2), Some(0)]);
1855
1856 let a = take(&list_array, &index, None).unwrap();
1857 let a: &$list_array_type = a.as_any().downcast_ref::<$list_array_type>().unwrap();
1858
1859 let expected_data = Int32Array::from(vec![
1862 Some(2),
1863 Some(3),
1864 Some(-1),
1865 Some(-2),
1866 Some(-1),
1867 Some(0),
1868 Some(0),
1869 Some(0),
1870 ])
1871 .into_data();
1872 let expected_offsets: [$offset_type; 6] = [0, 2, 2, 5, 5, 8];
1874 let expected_offsets = Buffer::from_slice_ref(&expected_offsets);
1875 let expected_list_data = ArrayData::builder(list_data_type)
1877 .len(5)
1878 .nulls(index.nulls().cloned())
1880 .add_buffer(expected_offsets)
1881 .add_child_data(expected_data)
1882 .build()
1883 .unwrap();
1884 let expected_list_array = $list_array_type::from(expected_list_data);
1885
1886 assert_eq!(a, &expected_list_array);
1887 }};
1888 }
1889
1890 macro_rules! test_take_list_with_value_nulls {
1891 ($offset_type:ty, $list_data_type:ident, $list_array_type:ident) => {{
1892 let value_data = Int32Array::from(vec![
1894 Some(0),
1895 None,
1896 Some(0),
1897 Some(-1),
1898 Some(-2),
1899 Some(3),
1900 None,
1901 Some(5),
1902 None,
1903 ])
1904 .into_data();
1905 let value_offsets: [$offset_type; 5] = [0, 3, 6, 7, 9];
1907 let value_offsets = Buffer::from_slice_ref(&value_offsets);
1908 let list_data_type =
1910 DataType::$list_data_type(Arc::new(Field::new_list_field(DataType::Int32, true)));
1911 let list_data = ArrayData::builder(list_data_type.clone())
1912 .len(4)
1913 .add_buffer(value_offsets)
1914 .null_bit_buffer(Some(Buffer::from([0b11111111])))
1915 .add_child_data(value_data)
1916 .build()
1917 .unwrap();
1918 let list_array = $list_array_type::from(list_data);
1919
1920 let index = UInt32Array::from(vec![Some(2), None, Some(1), Some(3), Some(0)]);
1922
1923 let a = take(&list_array, &index, None).unwrap();
1924 let a: &$list_array_type = a.as_any().downcast_ref::<$list_array_type>().unwrap();
1925
1926 let expected_data = Int32Array::from(vec![
1929 None,
1930 Some(-1),
1931 Some(-2),
1932 Some(3),
1933 Some(5),
1934 None,
1935 Some(0),
1936 None,
1937 Some(0),
1938 ])
1939 .into_data();
1940 let expected_offsets: [$offset_type; 6] = [0, 1, 1, 4, 6, 9];
1942 let expected_offsets = Buffer::from_slice_ref(&expected_offsets);
1943 let expected_list_data = ArrayData::builder(list_data_type)
1945 .len(5)
1946 .nulls(index.nulls().cloned())
1948 .add_buffer(expected_offsets)
1949 .add_child_data(expected_data)
1950 .build()
1951 .unwrap();
1952 let expected_list_array = $list_array_type::from(expected_list_data);
1953
1954 assert_eq!(a, &expected_list_array);
1955 }};
1956 }
1957
1958 macro_rules! test_take_list_with_nulls {
1959 ($offset_type:ty, $list_data_type:ident, $list_array_type:ident) => {{
1960 let value_data = Int32Array::from(vec![
1962 Some(0),
1963 None,
1964 Some(0),
1965 Some(-1),
1966 Some(-2),
1967 Some(3),
1968 Some(5),
1969 None,
1970 ])
1971 .into_data();
1972 let value_offsets: [$offset_type; 5] = [0, 3, 6, 6, 8];
1974 let value_offsets = Buffer::from_slice_ref(&value_offsets);
1975 let list_data_type =
1977 DataType::$list_data_type(Arc::new(Field::new_list_field(DataType::Int32, true)));
1978 let list_data = ArrayData::builder(list_data_type.clone())
1979 .len(4)
1980 .add_buffer(value_offsets)
1981 .null_bit_buffer(Some(Buffer::from([0b11111011])))
1982 .add_child_data(value_data)
1983 .build()
1984 .unwrap();
1985 let list_array = $list_array_type::from(list_data);
1986
1987 let index = UInt32Array::from(vec![Some(2), None, Some(1), Some(3), Some(0)]);
1989
1990 let a = take(&list_array, &index, None).unwrap();
1991 let a: &$list_array_type = a.as_any().downcast_ref::<$list_array_type>().unwrap();
1992
1993 let expected_data = Int32Array::from(vec![
1996 Some(-1),
1997 Some(-2),
1998 Some(3),
1999 Some(5),
2000 None,
2001 Some(0),
2002 None,
2003 Some(0),
2004 ])
2005 .into_data();
2006 let expected_offsets: [$offset_type; 6] = [0, 0, 0, 3, 5, 8];
2008 let expected_offsets = Buffer::from_slice_ref(&expected_offsets);
2009 let mut null_bits: [u8; 1] = [0; 1];
2011 bit_util::set_bit(&mut null_bits, 2);
2012 bit_util::set_bit(&mut null_bits, 3);
2013 bit_util::set_bit(&mut null_bits, 4);
2014 let expected_list_data = ArrayData::builder(list_data_type)
2015 .len(5)
2016 .null_bit_buffer(Some(Buffer::from(null_bits)))
2018 .add_buffer(expected_offsets)
2019 .add_child_data(expected_data)
2020 .build()
2021 .unwrap();
2022 let expected_list_array = $list_array_type::from(expected_list_data);
2023
2024 assert_eq!(a, &expected_list_array);
2025 }};
2026 }
2027
2028 fn test_take_list_view_generic<OffsetType: OffsetSizeTrait, ValuesType: ArrowPrimitiveType, F>(
2029 values: Vec<Option<Vec<Option<ValuesType::Native>>>>,
2030 take_indices: Vec<Option<usize>>,
2031 expected: Vec<Option<Vec<Option<ValuesType::Native>>>>,
2032 mapper: F,
2033 ) where
2034 F: Fn(GenericListViewArray<OffsetType>) -> GenericListViewArray<OffsetType>,
2035 {
2036 let mut list_view_array =
2037 GenericListViewBuilder::<OffsetType, _>::new(PrimitiveBuilder::<ValuesType>::new());
2038
2039 for value in values {
2040 list_view_array.append_option(value);
2041 }
2042 let list_view_array = list_view_array.finish();
2043 let list_view_array = mapper(list_view_array);
2044
2045 let mut indices = UInt64Builder::new();
2046 for idx in take_indices {
2047 indices.append_option(idx.map(|i| i.to_u64().unwrap()));
2048 }
2049 let indices = indices.finish();
2050
2051 let taken = take(&list_view_array, &indices, None)
2052 .unwrap()
2053 .as_list_view()
2054 .clone();
2055
2056 let mut expected_array =
2057 GenericListViewBuilder::<OffsetType, _>::new(PrimitiveBuilder::<ValuesType>::new());
2058 for value in expected {
2059 expected_array.append_option(value);
2060 }
2061 let expected_array = expected_array.finish();
2062
2063 assert_eq!(taken, expected_array);
2064 }
2065
2066 macro_rules! list_view_test_case {
2067 (values: $values:expr, indices: $indices:expr, expected: $expected: expr) => {{
2068 test_take_list_view_generic::<i32, Int8Type, _>($values, $indices, $expected, |x| x);
2069 test_take_list_view_generic::<i64, Int8Type, _>($values, $indices, $expected, |x| x);
2070 }};
2071 (values: $values:expr, transform: $fn:expr, indices: $indices:expr, expected: $expected: expr) => {{
2072 test_take_list_view_generic::<i32, Int8Type, _>($values, $indices, $expected, $fn);
2073 test_take_list_view_generic::<i64, Int8Type, _>($values, $indices, $expected, $fn);
2074 }};
2075 }
2076
2077 fn do_take_fixed_size_list_test<T>(
2078 length: <Int32Type as ArrowPrimitiveType>::Native,
2079 input_data: Vec<Option<Vec<Option<T::Native>>>>,
2080 indices: Vec<<UInt32Type as ArrowPrimitiveType>::Native>,
2081 expected_data: Vec<Option<Vec<Option<T::Native>>>>,
2082 ) where
2083 T: ArrowPrimitiveType,
2084 PrimitiveArray<T>: From<Vec<Option<T::Native>>>,
2085 {
2086 let indices = UInt32Array::from(indices);
2087
2088 let input_array = FixedSizeListArray::from_iter_primitive::<T, _, _>(input_data, length);
2089
2090 let output = take_fixed_size_list(&input_array, &indices, length as u32).unwrap();
2091
2092 let expected = FixedSizeListArray::from_iter_primitive::<T, _, _>(expected_data, length);
2093
2094 assert_eq!(&output, &expected)
2095 }
2096
2097 #[test]
2098 fn test_take_list() {
2099 test_take_list!(i32, List, ListArray);
2100 }
2101
2102 #[test]
2103 fn test_take_large_list() {
2104 test_take_list!(i64, LargeList, LargeListArray);
2105 }
2106
2107 #[test]
2108 fn test_take_list_with_value_nulls() {
2109 test_take_list_with_value_nulls!(i32, List, ListArray);
2110 }
2111
2112 #[test]
2113 fn test_take_large_list_with_value_nulls() {
2114 test_take_list_with_value_nulls!(i64, LargeList, LargeListArray);
2115 }
2116
2117 #[test]
2118 fn test_test_take_list_with_nulls() {
2119 test_take_list_with_nulls!(i32, List, ListArray);
2120 }
2121
2122 #[test]
2123 fn test_test_take_large_list_with_nulls() {
2124 test_take_list_with_nulls!(i64, LargeList, LargeListArray);
2125 }
2126
2127 #[test]
2128 fn test_test_take_list_view_reversed() {
2129 list_view_test_case! {
2131 values: vec![
2132 Some(vec![Some(1), None, Some(3)]),
2133 None,
2134 Some(vec![Some(7), Some(8), None]),
2135 ],
2136 indices: vec![Some(2), Some(1), Some(0)],
2137 expected: vec![
2138 Some(vec![Some(7), Some(8), None]),
2139 None,
2140 Some(vec![Some(1), None, Some(3)]),
2141 ]
2142 }
2143 }
2144
2145 #[test]
2146 fn test_take_list_view_null_indices() {
2147 list_view_test_case! {
2149 values: vec![
2150 Some(vec![Some(1), None, Some(3)]),
2151 None,
2152 Some(vec![Some(7), Some(8), None]),
2153 ],
2154 indices: vec![None, Some(0), None],
2155 expected: vec![None, Some(vec![Some(1), None, Some(3)]), None]
2156 }
2157 }
2158
2159 #[test]
2160 fn test_take_list_view_null_values() {
2161 list_view_test_case! {
2163 values: vec![
2164 Some(vec![Some(1), None, Some(3)]),
2165 None,
2166 Some(vec![Some(7), Some(8), None]),
2167 ],
2168 indices: vec![Some(1), Some(1), Some(1), None, None],
2169 expected: vec![None; 5]
2170 }
2171 }
2172
2173 #[test]
2174 fn test_take_list_view_sliced() {
2175 list_view_test_case! {
2177 values: vec![
2178 Some(vec![Some(1)]),
2179 None,
2180 None,
2181 Some(vec![Some(2), Some(3)]),
2182 Some(vec![Some(4), Some(5)]),
2183 None,
2184 ],
2185 transform: |l| l.slice(2, 4),
2186 indices: vec![Some(0), Some(3), None, Some(1), Some(2)],
2187 expected: vec![
2188 None, None, None, Some(vec![Some(2), Some(3)]), Some(vec![Some(4), Some(5)])
2189 ]
2190 }
2191 }
2192
2193 #[test]
2194 fn test_take_fixed_size_list() {
2195 do_take_fixed_size_list_test::<Int32Type>(
2196 3,
2197 vec![
2198 Some(vec![None, Some(1), Some(2)]),
2199 Some(vec![Some(3), Some(4), None]),
2200 Some(vec![Some(6), Some(7), Some(8)]),
2201 ],
2202 vec![2, 1, 0],
2203 vec![
2204 Some(vec![Some(6), Some(7), Some(8)]),
2205 Some(vec![Some(3), Some(4), None]),
2206 Some(vec![None, Some(1), Some(2)]),
2207 ],
2208 );
2209
2210 do_take_fixed_size_list_test::<UInt8Type>(
2211 1,
2212 vec![
2213 Some(vec![Some(1)]),
2214 Some(vec![Some(2)]),
2215 Some(vec![Some(3)]),
2216 Some(vec![Some(4)]),
2217 Some(vec![Some(5)]),
2218 Some(vec![Some(6)]),
2219 Some(vec![Some(7)]),
2220 Some(vec![Some(8)]),
2221 ],
2222 vec![2, 7, 0],
2223 vec![
2224 Some(vec![Some(3)]),
2225 Some(vec![Some(8)]),
2226 Some(vec![Some(1)]),
2227 ],
2228 );
2229
2230 do_take_fixed_size_list_test::<UInt64Type>(
2231 3,
2232 vec![
2233 Some(vec![Some(10), Some(11), Some(12)]),
2234 Some(vec![Some(13), Some(14), Some(15)]),
2235 None,
2236 Some(vec![Some(16), Some(17), Some(18)]),
2237 ],
2238 vec![3, 2, 1, 2, 0],
2239 vec![
2240 Some(vec![Some(16), Some(17), Some(18)]),
2241 None,
2242 Some(vec![Some(13), Some(14), Some(15)]),
2243 None,
2244 Some(vec![Some(10), Some(11), Some(12)]),
2245 ],
2246 );
2247 }
2248
2249 #[test]
2250 fn test_take_fixed_size_binary_with_nulls_indices() {
2251 let fsb = FixedSizeBinaryArray::try_from_sparse_iter_with_size(
2252 [
2253 Some(vec![0x01, 0x01, 0x01, 0x01]),
2254 Some(vec![0x02, 0x02, 0x02, 0x02]),
2255 Some(vec![0x03, 0x03, 0x03, 0x03]),
2256 Some(vec![0x04, 0x04, 0x04, 0x04]),
2257 ]
2258 .into_iter(),
2259 4,
2260 )
2261 .unwrap();
2262
2263 let indices = UInt32Array::from(vec![Some(0), None, None, Some(3)]);
2265
2266 let result = take_fixed_size_binary(&fsb, &indices, 4).unwrap();
2267 assert_eq!(result.len(), 4);
2268 assert_eq!(result.null_count(), 2);
2269 assert_eq!(
2270 result.nulls().unwrap().iter().collect::<Vec<_>>(),
2271 vec![true, false, false, true]
2272 );
2273 }
2274
2275 #[test]
2279 fn test_take_fixed_size_binary_with_nulls_indices_not_optimized_length() {
2280 let fsb = FixedSizeBinaryArray::try_from_sparse_iter_with_size(
2281 [
2282 Some(vec![0x01, 0x01, 0x01, 0x01, 0x01]),
2283 Some(vec![0x02, 0x02, 0x02, 0x02, 0x01]),
2284 Some(vec![0x03, 0x03, 0x03, 0x03, 0x01]),
2285 Some(vec![0x04, 0x04, 0x04, 0x04, 0x01]),
2286 ]
2287 .into_iter(),
2288 5,
2289 )
2290 .unwrap();
2291
2292 let indices = UInt32Array::from(vec![Some(0), None, None, Some(3)]);
2294
2295 let result = take_fixed_size_binary(&fsb, &indices, 5).unwrap();
2296 assert_eq!(result.len(), 4);
2297 assert_eq!(result.null_count(), 2);
2298 assert_eq!(
2299 result.nulls().unwrap().iter().collect::<Vec<_>>(),
2300 vec![true, false, false, true]
2301 );
2302 }
2303
2304 #[test]
2305 #[should_panic(expected = "index out of bounds: the len is 4 but the index is 1000")]
2306 fn test_take_list_out_of_bounds() {
2307 let value_data = Int32Array::from(vec![0, 0, 0, -1, -2, -1, 2, 3]).into_data();
2309 let value_offsets = Buffer::from_slice_ref([0, 3, 6, 8]);
2311 let list_data_type =
2313 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
2314 let list_data = ArrayData::builder(list_data_type)
2315 .len(3)
2316 .add_buffer(value_offsets)
2317 .add_child_data(value_data)
2318 .build()
2319 .unwrap();
2320 let list_array = ListArray::from(list_data);
2321
2322 let index = UInt32Array::from(vec![1000]);
2323
2324 take(&list_array, &index, None).unwrap();
2327 }
2328
2329 #[test]
2330 fn test_take_map() {
2331 let values = Int32Array::from(vec![1, 2, 3, 4]);
2332 let array =
2333 MapArray::new_from_strings(vec!["a", "b", "c", "a"].into_iter(), &values, &[0, 3, 4])
2334 .unwrap();
2335
2336 let index = UInt32Array::from(vec![0]);
2337
2338 let result = take(&array, &index, None).unwrap();
2339 let expected: ArrayRef = Arc::new(
2340 MapArray::new_from_strings(
2341 vec!["a", "b", "c"].into_iter(),
2342 &values.slice(0, 3),
2343 &[0, 3],
2344 )
2345 .unwrap(),
2346 );
2347 assert_eq!(&expected, &result);
2348 }
2349
2350 #[test]
2351 fn test_take_struct() {
2352 let array = create_test_struct(vec![
2353 Some((Some(true), Some(42))),
2354 Some((Some(false), Some(28))),
2355 Some((Some(false), Some(19))),
2356 Some((Some(true), Some(31))),
2357 None,
2358 ]);
2359
2360 let index = UInt32Array::from(vec![0, 3, 1, 0, 2, 4]);
2361 let actual = take(&array, &index, None).unwrap();
2362 let actual: &StructArray = actual.as_any().downcast_ref::<StructArray>().unwrap();
2363 assert_eq!(index.len(), actual.len());
2364 assert_eq!(1, actual.null_count());
2365
2366 let expected = create_test_struct(vec![
2367 Some((Some(true), Some(42))),
2368 Some((Some(true), Some(31))),
2369 Some((Some(false), Some(28))),
2370 Some((Some(true), Some(42))),
2371 Some((Some(false), Some(19))),
2372 None,
2373 ]);
2374
2375 assert_eq!(&expected, actual);
2376
2377 let nulls = NullBuffer::from(&[false, true, false, true, false, true]);
2378 let empty_struct_arr = StructArray::new_empty_fields(6, Some(nulls));
2379 let index = UInt32Array::from(vec![0, 2, 1, 4]);
2380 let actual = take(&empty_struct_arr, &index, None).unwrap();
2381
2382 let expected_nulls = NullBuffer::from(&[false, false, true, false]);
2383 let expected_struct_arr = StructArray::new_empty_fields(4, Some(expected_nulls));
2384 assert_eq!(&expected_struct_arr, actual.as_struct());
2385 }
2386
2387 #[test]
2388 fn test_take_struct_with_null_indices() {
2389 let array = create_test_struct(vec![
2390 Some((Some(true), Some(42))),
2391 Some((Some(false), Some(28))),
2392 Some((Some(false), Some(19))),
2393 Some((Some(true), Some(31))),
2394 None,
2395 ]);
2396
2397 let index = UInt32Array::from(vec![None, Some(3), Some(1), None, Some(0), Some(4)]);
2398 let actual = take(&array, &index, None).unwrap();
2399 let actual: &StructArray = actual.as_any().downcast_ref::<StructArray>().unwrap();
2400 assert_eq!(index.len(), actual.len());
2401 assert_eq!(3, actual.null_count()); let expected = create_test_struct(vec![
2404 None,
2405 Some((Some(true), Some(31))),
2406 Some((Some(false), Some(28))),
2407 None,
2408 Some((Some(true), Some(42))),
2409 None,
2410 ]);
2411
2412 assert_eq!(&expected, actual);
2413 }
2414
2415 #[test]
2416 fn test_take_out_of_bounds() {
2417 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(3), Some(6)]);
2418 let take_opt = TakeOptions { check_bounds: true };
2419
2420 let result = test_take_primitive_arrays::<Int64Type>(
2422 vec![Some(0), None, Some(2), Some(3), None],
2423 &index,
2424 Some(take_opt),
2425 vec![None],
2426 );
2427 assert!(result.is_err());
2428 }
2429
2430 #[test]
2431 #[should_panic(expected = "index out of bounds: the len is 4 but the index is 1000")]
2432 fn test_take_out_of_bounds_panic() {
2433 let index = UInt32Array::from(vec![Some(1000)]);
2434
2435 test_take_primitive_arrays::<Int64Type>(
2436 vec![Some(0), Some(1), Some(2), Some(3)],
2437 &index,
2438 None,
2439 vec![None],
2440 )
2441 .unwrap();
2442 }
2443
2444 #[test]
2445 fn test_null_array_smaller_than_indices() {
2446 let values = NullArray::new(2);
2447 let indices = UInt32Array::from(vec![Some(0), None, Some(15)]);
2448
2449 let result = take(&values, &indices, None).unwrap();
2450 let expected: ArrayRef = Arc::new(NullArray::new(3));
2451 assert_eq!(&result, &expected);
2452 }
2453
2454 #[test]
2455 fn test_null_array_larger_than_indices() {
2456 let values = NullArray::new(5);
2457 let indices = UInt32Array::from(vec![Some(0), None, Some(15)]);
2458
2459 let result = take(&values, &indices, None).unwrap();
2460 let expected: ArrayRef = Arc::new(NullArray::new(3));
2461 assert_eq!(&result, &expected);
2462 }
2463
2464 #[test]
2465 fn test_null_array_indices_out_of_bounds() {
2466 let values = NullArray::new(5);
2467 let indices = UInt32Array::from(vec![Some(0), None, Some(15)]);
2468
2469 let result = take(&values, &indices, Some(TakeOptions { check_bounds: true }));
2470 assert_eq!(
2471 result.unwrap_err().to_string(),
2472 "Compute error: Array index out of bounds, cannot get item at index 15 from 5 entries"
2473 );
2474 }
2475
2476 #[test]
2477 fn test_take_dict() {
2478 let mut dict_builder = StringDictionaryBuilder::<Int16Type>::new();
2479
2480 dict_builder.append("foo").unwrap();
2481 dict_builder.append("bar").unwrap();
2482 dict_builder.append("").unwrap();
2483 dict_builder.append_null();
2484 dict_builder.append("foo").unwrap();
2485 dict_builder.append("bar").unwrap();
2486 dict_builder.append("bar").unwrap();
2487 dict_builder.append("foo").unwrap();
2488
2489 let array = dict_builder.finish();
2490 let dict_values = array.values().clone();
2491 let dict_values = dict_values.as_any().downcast_ref::<StringArray>().unwrap();
2492
2493 let indices = UInt32Array::from(vec![
2494 Some(0), Some(7), None, Some(5), Some(6), Some(2), Some(3), ]);
2502
2503 let result = take(&array, &indices, None).unwrap();
2504 let result = result
2505 .as_any()
2506 .downcast_ref::<DictionaryArray<Int16Type>>()
2507 .unwrap();
2508
2509 let result_values: StringArray = result.values().to_data().into();
2510
2511 let expected_values = StringArray::from(vec!["foo", "bar", ""]);
2513 assert_eq!(&expected_values, dict_values);
2514 assert_eq!(&expected_values, &result_values);
2515
2516 let expected_keys = Int16Array::from(vec![
2517 Some(0),
2518 Some(0),
2519 None,
2520 Some(1),
2521 Some(1),
2522 Some(2),
2523 None,
2524 ]);
2525 assert_eq!(result.keys(), &expected_keys);
2526 }
2527
2528 fn build_generic_list<S, T>(data: Vec<Option<Vec<T::Native>>>) -> GenericListArray<S>
2529 where
2530 S: OffsetSizeTrait + 'static,
2531 T: ArrowPrimitiveType,
2532 PrimitiveArray<T>: From<Vec<Option<T::Native>>>,
2533 {
2534 GenericListArray::from_iter_primitive::<T, _, _>(
2535 data.iter()
2536 .map(|x| x.as_ref().map(|x| x.iter().map(|x| Some(*x)))),
2537 )
2538 }
2539
2540 fn test_take_sliced_list_generic<S: OffsetSizeTrait + 'static>() {
2541 let list = build_generic_list::<S, Int32Type>(vec![
2542 Some(vec![0, 1]),
2543 Some(vec![2, 3, 4]),
2544 None,
2545 Some(vec![]),
2546 Some(vec![5, 6]),
2547 Some(vec![7]),
2548 ]);
2549 let sliced = list.slice(1, 4);
2550 let indices = UInt32Array::from(vec![Some(3), Some(0), None, Some(2), Some(1)]);
2551
2552 let taken = take(&sliced, &indices, None).unwrap();
2553 let taken = taken.as_list::<S>();
2554
2555 let expected = build_generic_list::<S, Int32Type>(vec![
2556 Some(vec![5, 6]),
2557 Some(vec![2, 3, 4]),
2558 None,
2559 Some(vec![]),
2560 None,
2561 ]);
2562
2563 assert_eq!(taken, &expected);
2564 }
2565
2566 fn test_take_sliced_list_with_value_nulls_generic<S: OffsetSizeTrait + 'static>() {
2567 let list = GenericListArray::<S>::from_iter_primitive::<Int32Type, _, _>(vec![
2568 Some(vec![Some(10)]),
2569 Some(vec![None, Some(1)]),
2570 None,
2571 Some(vec![Some(2), None]),
2572 Some(vec![]),
2573 Some(vec![Some(3)]),
2574 ]);
2575 let sliced = list.slice(1, 4);
2576 let indices = UInt32Array::from(vec![Some(2), Some(0), None, Some(3), Some(1)]);
2577
2578 let taken = take(&sliced, &indices, None).unwrap();
2579 let taken = taken.as_list::<S>();
2580
2581 let expected = GenericListArray::<S>::from_iter_primitive::<Int32Type, _, _>(vec![
2582 Some(vec![Some(2), None]),
2583 Some(vec![None, Some(1)]),
2584 None,
2585 Some(vec![]),
2586 None,
2587 ]);
2588
2589 assert_eq!(taken, &expected);
2590 }
2591
2592 #[test]
2593 fn test_take_sliced_list() {
2594 test_take_sliced_list_generic::<i32>();
2595 }
2596
2597 #[test]
2598 fn test_take_sliced_large_list() {
2599 test_take_sliced_list_generic::<i64>();
2600 }
2601
2602 #[test]
2603 fn test_take_sliced_list_with_value_nulls() {
2604 test_take_sliced_list_with_value_nulls_generic::<i32>();
2605 }
2606
2607 #[test]
2608 fn test_take_sliced_large_list_with_value_nulls() {
2609 test_take_sliced_list_with_value_nulls_generic::<i64>();
2610 }
2611
2612 #[test]
2613 fn test_take_runs() {
2614 let logical_array: Vec<i32> = vec![1_i32, 1, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 2];
2615
2616 let mut builder = PrimitiveRunBuilder::<Int32Type, Int32Type>::new();
2617 builder.extend(logical_array.into_iter().map(Some));
2618 let run_array = builder.finish();
2619
2620 let take_indices: PrimitiveArray<Int32Type> =
2621 vec![7, 2, 3, 7, 11, 4, 6].into_iter().collect();
2622
2623 let take_out = take_run(&run_array, &take_indices).unwrap();
2624
2625 assert_eq!(take_out.len(), 7);
2626 assert_eq!(
2628 take_out.run_ends().values().len(),
2629 2,
2630 "expected two physical runs"
2631 );
2632 assert_eq!(take_out.run_ends().values(), &[5_i32, 7]);
2633
2634 let take_out_values = take_out.values().as_primitive::<Int32Type>();
2635 assert_eq!(take_out_values.values(), &[2, 1]);
2636 }
2637
2638 #[test]
2639 fn test_take_runs_sliced() {
2640 let logical_array: Vec<i32> = vec![1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6];
2641
2642 let mut builder = PrimitiveRunBuilder::<Int32Type, Int32Type>::new();
2643 builder.extend(logical_array.into_iter().map(Some));
2644 let run_array = builder.finish();
2645
2646 let run_array = run_array.slice(4, 6); let take_indices: PrimitiveArray<Int32Type> = vec![0, 5, 5, 1, 4].into_iter().collect();
2649
2650 let result = take_run(&run_array, &take_indices).unwrap();
2651 let result = result.downcast::<Int32Array>().unwrap();
2652
2653 assert_eq!(
2655 result.run_ends().values().len(),
2656 4,
2657 "expected four physical runs"
2658 );
2659 assert_eq!(result.run_ends().values(), &[1_i32, 3, 4, 5]);
2660
2661 let expected = vec![3, 5, 5, 3, 4];
2662 let actual = result.into_iter().flatten().collect::<Vec<_>>();
2663
2664 assert_eq!(expected, actual);
2665 }
2666
2667 #[test]
2668 fn test_take_value_index_from_fixed_list() {
2669 let list = FixedSizeListArray::from_iter_primitive::<Int32Type, _, _>(
2670 vec![
2671 Some(vec![Some(1), Some(2), None]),
2672 Some(vec![Some(4), None, Some(6)]),
2673 None,
2674 Some(vec![None, Some(8), Some(9)]),
2675 ],
2676 3,
2677 );
2678
2679 let indices = UInt32Array::from(vec![2, 1, 0]);
2680 let indexed = take_value_indices_from_fixed_size_list(&list, &indices, 3).unwrap();
2681
2682 assert_eq!(indexed, UInt32Array::from(vec![6, 7, 8, 3, 4, 5, 0, 1, 2]));
2683
2684 let indices = UInt32Array::from(vec![3, 2, 1, 2, 0]);
2685 let indexed = take_value_indices_from_fixed_size_list(&list, &indices, 3).unwrap();
2686
2687 assert_eq!(
2688 indexed,
2689 UInt32Array::from(vec![9, 10, 11, 6, 7, 8, 3, 4, 5, 6, 7, 8, 0, 1, 2])
2690 );
2691 }
2692
2693 #[test]
2694 fn test_take_null_indices() {
2695 let indices = Int32Array::new(
2697 vec![1, 2, 400, 400].into(),
2698 Some(NullBuffer::from(vec![true, true, false, false])),
2699 );
2700 let values = Int32Array::from(vec![1, 23, 4, 5]);
2701 let r = take(&values, &indices, None).unwrap();
2702 let values = r
2703 .as_primitive::<Int32Type>()
2704 .into_iter()
2705 .collect::<Vec<_>>();
2706 assert_eq!(&values, &[Some(23), Some(4), None, None])
2707 }
2708
2709 #[test]
2710 fn test_take_fixed_size_list_null_indices() {
2711 let indices = Int32Array::from_iter([Some(0), None]);
2712 let values = Arc::new(Int32Array::from(vec![0, 1, 2, 3]));
2713 let arr_field = Arc::new(Field::new_list_field(values.data_type().clone(), true));
2714 let values = FixedSizeListArray::try_new(arr_field, 2, values, None).unwrap();
2715
2716 let r = take(&values, &indices, None).unwrap();
2717 let values = r
2718 .as_fixed_size_list()
2719 .values()
2720 .as_primitive::<Int32Type>()
2721 .into_iter()
2722 .collect::<Vec<_>>();
2723 assert_eq!(values, &[Some(0), Some(1), None, None])
2724 }
2725
2726 #[test]
2727 fn test_take_bytes_null_indices() {
2728 let indices = Int32Array::new(
2729 vec![0, 1, 400, 400].into(),
2730 Some(NullBuffer::from_iter(vec![true, true, false, false])),
2731 );
2732 let values = StringArray::from(vec![Some("foo"), None]);
2733 let r = take(&values, &indices, None).unwrap();
2734 let values = r.as_string::<i32>().iter().collect::<Vec<_>>();
2735 assert_eq!(&values, &[Some("foo"), None, None, None])
2736 }
2737
2738 #[test]
2739 fn test_take_union_sparse() {
2740 let structs = create_test_struct(vec![
2741 Some((Some(true), Some(42))),
2742 Some((Some(false), Some(28))),
2743 Some((Some(false), Some(19))),
2744 Some((Some(true), Some(31))),
2745 None,
2746 ]);
2747 let strings = StringArray::from(vec![Some("a"), None, Some("c"), None, Some("d")]);
2748 let type_ids = [1; 5].into_iter().collect::<ScalarBuffer<i8>>();
2749
2750 let union_fields = [
2751 (
2752 0,
2753 Arc::new(Field::new("f1", structs.data_type().clone(), true)),
2754 ),
2755 (
2756 1,
2757 Arc::new(Field::new("f2", strings.data_type().clone(), true)),
2758 ),
2759 ]
2760 .into_iter()
2761 .collect();
2762 let children = vec![Arc::new(structs) as Arc<dyn Array>, Arc::new(strings)];
2763 let array = UnionArray::try_new(union_fields, type_ids, None, children).unwrap();
2764
2765 let indices = vec![0, 3, 1, 0, 2, 4];
2766 let index = UInt32Array::from(indices.clone());
2767 let actual = take(&array, &index, None).unwrap();
2768 let actual = actual.as_any().downcast_ref::<UnionArray>().unwrap();
2769 let strings = actual.child(1);
2770 let strings = strings.as_any().downcast_ref::<StringArray>().unwrap();
2771
2772 let actual = strings.iter().collect::<Vec<_>>();
2773 let expected = vec![Some("a"), None, None, Some("a"), Some("c"), Some("d")];
2774 assert_eq!(expected, actual);
2775 }
2776
2777 #[test]
2778 fn test_take_union_dense() {
2779 let type_ids = vec![0, 1, 1, 0, 0, 1, 0];
2780 let offsets = vec![0, 0, 1, 1, 2, 2, 3];
2781 let ints = vec![10, 20, 30, 40];
2782 let strings = vec![Some("a"), None, Some("c"), Some("d")];
2783
2784 let indices = vec![0, 3, 1, 0, 2, 4];
2785
2786 let taken_type_ids = vec![0, 0, 1, 0, 1, 0];
2787 let taken_offsets = vec![0, 1, 0, 2, 1, 3];
2788 let taken_ints = vec![10, 20, 10, 30];
2789 let taken_strings = vec![Some("a"), None];
2790
2791 let type_ids = <ScalarBuffer<i8>>::from(type_ids);
2792 let offsets = <ScalarBuffer<i32>>::from(offsets);
2793 let ints = UInt32Array::from(ints);
2794 let strings = StringArray::from(strings);
2795
2796 let union_fields = [
2797 (
2798 0,
2799 Arc::new(Field::new("f1", ints.data_type().clone(), true)),
2800 ),
2801 (
2802 1,
2803 Arc::new(Field::new("f2", strings.data_type().clone(), true)),
2804 ),
2805 ]
2806 .into_iter()
2807 .collect();
2808
2809 let array = UnionArray::try_new(
2810 union_fields,
2811 type_ids,
2812 Some(offsets),
2813 vec![Arc::new(ints), Arc::new(strings)],
2814 )
2815 .unwrap();
2816
2817 let index = UInt32Array::from(indices);
2818
2819 let actual = take(&array, &index, None).unwrap();
2820 let actual = actual.as_any().downcast_ref::<UnionArray>().unwrap();
2821
2822 assert_eq!(actual.offsets(), Some(&ScalarBuffer::from(taken_offsets)));
2823 assert_eq!(actual.type_ids(), &ScalarBuffer::from(taken_type_ids));
2824 assert_eq!(
2825 UInt32Array::from(actual.child(0).to_data()),
2826 UInt32Array::from(taken_ints)
2827 );
2828 assert_eq!(
2829 StringArray::from(actual.child(1).to_data()),
2830 StringArray::from(taken_strings)
2831 );
2832 }
2833
2834 #[test]
2835 fn test_take_union_dense_using_builder() {
2836 let mut builder = UnionBuilder::new_dense();
2837
2838 builder.append::<Int32Type>("a", 1).unwrap();
2839 builder.append::<Float64Type>("b", 3.0).unwrap();
2840 builder.append::<Int32Type>("a", 4).unwrap();
2841 builder.append::<Int32Type>("a", 5).unwrap();
2842 builder.append::<Float64Type>("b", 2.0).unwrap();
2843
2844 let union = builder.build().unwrap();
2845
2846 let indices = UInt32Array::from(vec![2, 0, 1, 2]);
2847
2848 let mut builder = UnionBuilder::new_dense();
2849
2850 builder.append::<Int32Type>("a", 4).unwrap();
2851 builder.append::<Int32Type>("a", 1).unwrap();
2852 builder.append::<Float64Type>("b", 3.0).unwrap();
2853 builder.append::<Int32Type>("a", 4).unwrap();
2854
2855 let taken = builder.build().unwrap();
2856
2857 assert_eq!(
2858 taken.to_data(),
2859 take(&union, &indices, None).unwrap().to_data()
2860 );
2861 }
2862
2863 #[test]
2864 fn test_take_union_dense_all_match_issue_6206() {
2865 let fields = UnionFields::from_fields(vec![Field::new("a", DataType::Int64, false)]);
2866 let ints = Arc::new(Int64Array::from(vec![1, 2, 3, 4, 5]));
2867
2868 let array = UnionArray::try_new(
2869 fields,
2870 ScalarBuffer::from(vec![0_i8, 0, 0, 0, 0]),
2871 Some(ScalarBuffer::from_iter(0_i32..5)),
2872 vec![ints],
2873 )
2874 .unwrap();
2875
2876 let indicies = Int64Array::from(vec![0, 2, 4]);
2877 let array = take(&array, &indicies, None).unwrap();
2878 assert_eq!(array.len(), 3);
2879 }
2880
2881 fn offset_overflow_fixture() -> (StringArray, usize) {
2886 let value_len = 1_000_000;
2887 let values = StringArray::from(vec![Some("a".repeat(value_len))]);
2888 let n = i32::MAX as usize / value_len + 1;
2889 (values, n)
2890 }
2891
2892 #[test]
2893 fn test_take_bytes_offset_overflow() {
2894 let (values, n) = offset_overflow_fixture();
2895 let indices = Int32Array::from(vec![0; n]);
2896 assert!(matches!(
2897 take(&values, &indices, None),
2898 Err(ArrowError::OffsetOverflowError(_))
2899 ));
2900 }
2901
2902 #[test]
2905 fn test_take_bytes_offset_overflow_nullable() {
2906 let (values, n) = offset_overflow_fixture();
2907 let validity =
2910 NullBuffer::from_iter(std::iter::once(false).chain(std::iter::repeat_n(true, n)));
2911 let indices = Int32Array::new(vec![0i32; n + 1].into(), Some(validity));
2912
2913 assert!(matches!(
2914 take(&values, &indices, None),
2915 Err(ArrowError::OffsetOverflowError(_))
2916 ));
2917 }
2918
2919 #[test]
2920 fn test_take_run_empty_indices() {
2921 let mut builder = PrimitiveRunBuilder::<Int32Type, Int32Type>::new();
2922 builder.extend([Some(1), Some(1), Some(2), Some(2)]);
2923 let run_array = builder.finish();
2924
2925 let logical_indices: PrimitiveArray<Int32Type> = PrimitiveArray::from(Vec::<i32>::new());
2926
2927 let result = take_impl(&run_array, &logical_indices).expect("take_run with empty indices");
2928
2929 assert_eq!(result.len(), 0);
2931 assert_eq!(result.null_count(), 0);
2932
2933 let run_result = result
2936 .as_any()
2937 .downcast_ref::<RunArray<Int32Type>>()
2938 .expect("result should be a RunArray");
2939 assert_eq!(run_result.run_ends().len(), 0);
2940 assert_eq!(run_result.values().len(), 0);
2941 }
2942
2943 #[test]
2944 fn test_take_run_end_encoded_merges_identical_runs() {
2945 let mut builder = PrimitiveRunBuilder::<Int32Type, Int32Type>::new();
2949 builder.extend([1, 1, 0, 0, 1, 1].into_iter().map(Some));
2950 let ree = builder.finish();
2951
2952 let indexes = Int32Array::from_iter_values(vec![0, 1, 4, 5]);
2953 let result = take(&ree, &indexes, None).unwrap();
2954 let result = result
2955 .as_run::<Int32Type>()
2956 .downcast::<Int32Array>()
2957 .unwrap();
2958
2959 assert_eq!(
2961 result.run_ends().values().len(),
2962 1,
2963 "expected a single physical run"
2964 );
2965 assert_eq!(result.run_ends().values(), &[4_i32]);
2966
2967 let actual = result.into_iter().flatten().collect::<Vec<_>>();
2968 assert_eq!(actual, vec![1, 1, 1, 1]);
2969 }
2970
2971 #[test]
2972 fn test_take_run_end_encoded_merges_identical_string_runs() {
2973 let mut builder = StringRunBuilder::<Int32Type>::new();
2974 builder.extend(
2975 ["bob", "bob", "alice", "alice", "bob", "bob"]
2976 .into_iter()
2977 .map(Some),
2978 );
2979 let ree = builder.finish();
2980
2981 let indexes = Int32Array::from_iter_values(vec![0, 1, 4, 5]);
2982 let result = take(&ree, &indexes, None).unwrap();
2983 let result = result
2984 .as_run::<Int32Type>()
2985 .downcast::<StringArray>()
2986 .unwrap();
2987
2988 assert_eq!(
2990 result.run_ends().values().len(),
2991 1,
2992 "expected a single physical run"
2993 );
2994 assert_eq!(result.run_ends().values(), &[4_i32]);
2995
2996 let actual = result.into_iter().flatten().collect::<Vec<_>>();
2997 assert_eq!(actual, vec!["bob", "bob", "bob", "bob"]);
2998 }
2999
3000 #[test]
3001 fn test_take_run_end_encoded_mixed_runs() {
3002 let mut builder = StringRunBuilder::<Int32Type>::new();
3005 builder.extend(
3006 ["bob", "bob", "alice", "alice", "bob", "bob", "eve", "eve"]
3007 .into_iter()
3008 .map(Some),
3009 );
3010 let ree = builder.finish();
3011
3012 let indexes = Int32Array::from_iter_values(vec![0, 0, 1, 4, 5, 2, 3, 2, 6, 7, 6]);
3014 let result = take(&ree, &indexes, None).unwrap();
3015 let result = result
3016 .as_run::<Int32Type>()
3017 .downcast::<StringArray>()
3018 .unwrap();
3019
3020 println!("run_ends_raw: {:?}", result.run_ends());
3023 println!("run_ends: {:?}", result.run_ends().values());
3024 println!("values : {:?}", result.values());
3025 assert_eq!(
3026 result.run_ends().values().len(),
3027 3,
3028 "expected three physical runs"
3029 );
3030 assert_eq!(result.run_ends().values(), &[5_i32, 8, 11]);
3031
3032 let actual = result.into_iter().flatten().collect::<Vec<_>>();
3033 assert_eq!(
3034 actual,
3035 vec![
3036 "bob", "bob", "bob", "bob", "bob", "alice", "alice", "alice", "eve", "eve", "eve"
3037 ]
3038 );
3039 }
3040}