1use std::fmt::Display;
8use std::mem::ManuallyDrop;
9use std::sync::Arc;
10
11use arrow_array::builder::UInt32Builder;
12use arrow_array::cast::AsArray;
13use arrow_array::types::*;
14use arrow_array::*;
15use arrow_buffer::{
16 ArrowNativeType, BooleanBuffer, Buffer, MutableBuffer, NullBuffer, NullBufferBuilder,
17 OffsetBuffer, RunEndBuffer, ScalarBuffer, bit_util,
18};
19use arrow_cmp::make_comparator;
20use arrow_data::{ArrayData, transform::MutableArrayData};
21use arrow_schema::{ArrowError, DataType, FieldRef, SortOptions, UnionFields, UnionMode};
22
23use num_traits::{CheckedAdd, Zero};
24
25pub fn take(
77 values: &dyn Array,
78 indices: &dyn Array,
79 options: Option<TakeOptions>,
80) -> Result<ArrayRef, ArrowError> {
81 let options = options.unwrap_or_default();
82 downcast_integer_array!(
83 indices => {
84 let indices = indices.to_indices();
85 if options.check_bounds {
86 check_bounds(values.len(), &indices)?;
87 }
88 take_impl::<_, true>(values, &indices)
89 },
90 d => Err(ArrowError::InvalidArgumentError(format!("Take only supported for integers, got {d:?}")))
91 )
92}
93
94pub fn take_arrays(
143 arrays: &[ArrayRef],
144 indices: &dyn Array,
145 options: Option<TakeOptions>,
146) -> Result<Vec<ArrayRef>, ArrowError> {
147 arrays
148 .iter()
149 .map(|array| take(array.as_ref(), indices, options.clone()))
150 .collect()
151}
152
153pub unsafe fn take_arrays_unchecked(
165 arrays: &[ArrayRef],
166 indices: &dyn Array,
167) -> Result<Vec<ArrayRef>, ArrowError> {
168 downcast_integer_array!(
169 indices => {
170 let indices = indices.to_indices();
171 arrays
172 .iter()
173 .map(|array| take_impl::<_, false>(array.as_ref(), &indices))
174 .collect()
175 },
176 d => Err(ArrowError::InvalidArgumentError(format!("Take only supported for integers, got {d:?}")))
177 )
178}
179
180fn check_bounds<T: ArrowPrimitiveType>(
182 len: usize,
183 indices: &PrimitiveArray<T>,
184) -> Result<(), ArrowError>
185where
186 T::Native: Display,
187{
188 let Some(len) = T::Native::from_usize(len) else {
189 return if T::DATA_TYPE.is_integer() {
190 Ok(())
192 } else {
193 Err(ArrowError::ComputeError("Cast to usize failed".to_string()))
194 };
195 };
196
197 let in_bounds = indices.values().iter().fold(true, |in_bounds, &i| {
200 in_bounds & (i >= T::Native::ZERO) & (i < len)
201 });
202 if in_bounds {
203 Ok(())
204 } else if indices.null_count() > 0 {
205 indices.iter().flatten().try_for_each(|index| {
206 if index >= len {
207 return Err(ArrowError::ComputeError(format!(
208 "Array index out of bounds, cannot get item at index {index} from {len} entries"
209 )));
210 }
211 Ok(())
212 })
213 } else {
214 for &index in indices.values() {
215 if index < T::Native::ZERO || index >= len {
216 return Err(ArrowError::ComputeError(format!(
217 "Array index out of bounds, cannot get item at index {index} from {len} entries"
218 )));
219 }
220 }
221 Ok(())
222 }
223}
224
225#[inline(never)]
226fn take_impl<IndexType: ArrowPrimitiveType, const VALIDATE_INDICES: bool>(
227 values: &dyn Array,
228 indices: &PrimitiveArray<IndexType>,
229) -> Result<ArrayRef, ArrowError> {
230 if indices.is_empty() {
231 if let DataType::Union(fields, _) = values.data_type()
232 && fields.is_empty()
233 {
234 return Ok(values.slice(0, 0));
237 }
238 return Ok(new_empty_array(values.data_type()));
239 }
240 downcast_primitive_array! {
241 values => Ok(Arc::new(take_primitive::<_, _, VALIDATE_INDICES>(values, indices)?)),
242 DataType::Boolean => {
243 let values = values.as_any().downcast_ref::<BooleanArray>().unwrap();
244 Ok(Arc::new(take_boolean::<_, VALIDATE_INDICES>(values, indices)))
245 }
246 DataType::Utf8 => {
247 Ok(Arc::new(take_bytes::<_, _, VALIDATE_INDICES>(values.as_string::<i32>(), indices)?))
248 }
249 DataType::LargeUtf8 => {
250 Ok(Arc::new(take_bytes::<_, _, VALIDATE_INDICES>(values.as_string::<i64>(), indices)?))
251 }
252 DataType::Utf8View => {
253 Ok(Arc::new(take_byte_view::<_, _, VALIDATE_INDICES>(values.as_string_view(), indices)?))
254 }
255 DataType::List(_) => {
256 Ok(Arc::new(take_list::<_, Int32Type, VALIDATE_INDICES>(values.as_list(), indices)?))
257 }
258 DataType::LargeList(_) => {
259 Ok(Arc::new(take_list::<_, Int64Type, VALIDATE_INDICES>(values.as_list(), indices)?))
260 }
261 DataType::ListView(_) => {
262 Ok(Arc::new(take_list_view::<_, Int32Type, VALIDATE_INDICES>(values.as_list_view(), indices)?))
263 }
264 DataType::LargeListView(_) => {
265 Ok(Arc::new(take_list_view::<_, Int64Type, VALIDATE_INDICES>(values.as_list_view(), indices)?))
266 }
267 DataType::FixedSizeList(_, length) => {
268 let values = values
269 .as_any()
270 .downcast_ref::<FixedSizeListArray>()
271 .unwrap();
272 Ok(Arc::new(take_fixed_size_list::<_, VALIDATE_INDICES>(
273 values,
274 indices,
275 *length as u32,
276 )?))
277 }
278 DataType::Map(field, ordered) => {
279 let list_arr = ListArray::from(values.as_map().clone());
280 let list_data = take_list::<_, Int32Type, VALIDATE_INDICES>(&list_arr, indices)?;
281 let (_, offsets, entries, nulls) = list_data.into_parts();
282 let entries = entries.as_struct().clone();
283 Ok(Arc::new(MapArray::try_new(
284 field.clone(),
285 offsets,
286 entries,
287 nulls,
288 *ordered,
289 )?))
290 }
291 DataType::Struct(fields) => {
292 let array: &StructArray = values.as_struct();
293 let arrays = array
294 .columns()
295 .iter()
296 .map(|a| take_impl::<_, VALIDATE_INDICES>(a.as_ref(), indices))
297 .collect::<Result<Vec<ArrayRef>, _>>()?;
298 let fields: Vec<(FieldRef, ArrayRef)> =
299 fields.iter().cloned().zip(arrays).collect();
300
301 let is_valid: Buffer = indices
303 .iter()
304 .map(|index| {
305 if let Some(index) = index {
306 array.is_valid(index.to_usize().unwrap())
307 } else {
308 false
309 }
310 })
311 .collect();
312
313 if fields.is_empty() {
314 let nulls = NullBuffer::new(BooleanBuffer::new(is_valid, 0, indices.len()));
315 Ok(Arc::new(StructArray::new_empty_fields(indices.len(), Some(nulls))))
316 } else {
317 Ok(Arc::new(StructArray::from((fields, is_valid))) as ArrayRef)
318 }
319 }
320 DataType::Dictionary(_, _) => downcast_dictionary_array! {
321 values => Ok(Arc::new(take_dict::<_, _, VALIDATE_INDICES>(values, indices)?)),
322 t => unimplemented!("Take not supported for dictionary type {:?}", t)
323 }
324 DataType::RunEndEncoded(_, _) => downcast_run_array! {
325 values => Ok(Arc::new(take_run(values, indices)?)),
326 t => unimplemented!("Take not supported for run type {:?}", t)
327 }
328 DataType::Binary => {
329 Ok(Arc::new(take_bytes::<_, _, VALIDATE_INDICES>(values.as_binary::<i32>(), indices)?))
330 }
331 DataType::LargeBinary => {
332 Ok(Arc::new(take_bytes::<_, _, VALIDATE_INDICES>(values.as_binary::<i64>(), indices)?))
333 }
334 DataType::BinaryView => {
335 Ok(Arc::new(take_byte_view::<_, _, VALIDATE_INDICES>(values.as_binary_view(), indices)?))
336 }
337 DataType::FixedSizeBinary(size) => {
338 let values = values
339 .as_any()
340 .downcast_ref::<FixedSizeBinaryArray>()
341 .unwrap();
342 Ok(Arc::new(take_fixed_size_binary::<_, VALIDATE_INDICES>(values, indices, *size)?))
343 }
344 DataType::Null => {
345 if values.len() >= indices.len() {
347 Ok(values.slice(0, indices.len()))
350 } else {
351 Ok(new_null_array(&DataType::Null, indices.len()))
353 }
354 }
355 DataType::Union(fields, UnionMode::Sparse) => {
356 let values = values.as_any().downcast_ref::<UnionArray>().unwrap();
357 let (type_ids, null_type_id) =
358 take_union_type_ids(fields, values.type_ids(), indices)?;
359 let children = fields
360 .iter()
361 .map(|(type_id, _)| {
362 take_sparse_union_child::<_, VALIDATE_INDICES>(
363 values.child(type_id),
364 null_type_id == Some(type_id),
365 indices,
366 )
367 })
368 .collect::<Result<Vec<_>, _>>()?;
369 let array = UnionArray::try_new(fields.clone(), type_ids, None, children)?;
370 Ok(Arc::new(array))
371 }
372 DataType::Union(fields, UnionMode::Dense) => {
373 let values = values.as_any().downcast_ref::<UnionArray>().unwrap();
374
375 let (type_ids, _) = take_union_type_ids(fields, values.type_ids(), indices)?;
376 let type_ids = PrimitiveArray::<Int8Type>::try_new(type_ids, None)?;
377 let offsets = <PrimitiveArray<Int32Type>>::try_new(
380 take_native::<_, _, VALIDATE_INDICES>(values.offsets().unwrap(), indices),
381 indices.nulls().cloned(),
382 )?;
383
384 let children = fields.iter()
385 .map(|(field_type_id, _)| {
386 let mask = BooleanArray::from_unary(&type_ids, |value_type_id| value_type_id == field_type_id);
387
388 let indices = crate::filter::filter(&offsets, &mask)?;
389
390 let values = values.child(field_type_id);
391
392 take_impl::<_, VALIDATE_INDICES>(values, indices.as_primitive::<Int32Type>())
393 })
394 .collect::<Result<_, _>>()?;
395
396 let mut child_offsets = [0; 128];
397
398 let offsets = type_ids.values()
399 .iter()
400 .map(|&i| {
401 let offset = child_offsets[i as usize];
402
403 child_offsets[i as usize] += 1;
404
405 offset
406 })
407 .collect();
408
409 let (_, type_ids, _) = type_ids.into_parts();
410
411 let array = UnionArray::try_new(fields.clone(), type_ids, Some(offsets), children)?;
412
413 Ok(Arc::new(array))
414 }
415 t => unimplemented!("Take not supported for data type {:?}", t)
416 }
417}
418
419fn take_union_type_ids<IndexType: ArrowPrimitiveType>(
430 fields: &UnionFields,
431 type_ids: &ScalarBuffer<i8>,
432 indices: &PrimitiveArray<IndexType>,
433) -> Result<(ScalarBuffer<i8>, Option<i8>), ArrowError> {
434 if indices.null_count() == 0 {
435 return Ok((take_native::<_, _, true>(type_ids, indices), None));
436 }
437
438 let null_type_id = union_null_type_id(fields)?;
439 let taken_type_ids = take_native::<_, _, true>(type_ids, indices);
440 let type_ids = indices
441 .iter()
442 .zip(&taken_type_ids)
443 .map(|(index, &type_id)| {
444 if index.is_some() {
445 type_id
446 } else {
447 null_type_id
448 }
449 })
450 .collect::<ScalarBuffer<_>>();
451 Ok((type_ids, Some(null_type_id)))
452}
453
454fn union_null_type_id(fields: &UnionFields) -> Result<i8, ArrowError> {
456 fields
457 .iter()
458 .find_map(|(type_id, field)| field_can_represent_take_null(field).then_some(type_id))
459 .ok_or_else(|| {
460 ArrowError::ComputeError(
461 "Cannot take null indices from a union with no field that can represent nulls"
462 .into(),
463 )
464 })
465}
466
467fn field_can_represent_take_null(field: &FieldRef) -> bool {
473 if !field.is_nullable() {
474 return false;
475 }
476 match field.data_type() {
477 DataType::RunEndEncoded(_, values) => field_can_represent_take_null(values),
478 DataType::Union(fields, _) => fields
479 .iter()
480 .any(|(_, child)| field_can_represent_take_null(child)),
481 _ => true,
482 }
483}
484
485fn take_sparse_union_child<IndexType: ArrowPrimitiveType, const VALIDATE_INDICES: bool>(
492 values: &dyn Array,
493 represent_nulls: bool,
494 indices: &PrimitiveArray<IndexType>,
495) -> Result<ArrayRef, ArrowError> {
496 if represent_nulls || indices.null_count() == 0 {
497 return take_impl::<_, VALIDATE_INDICES>(values, indices);
498 }
499
500 if values.is_empty() {
501 return Ok(make_array(
505 new_null_array(values.data_type(), indices.len())
506 .to_data()
507 .into_builder()
508 .nulls(None)
509 .build()?,
510 ));
511 }
512
513 take_impl::<_, VALIDATE_INDICES>(values, &indices_without_nulls(indices))
514}
515
516fn indices_without_nulls<IndexType: ArrowPrimitiveType>(
518 indices: &PrimitiveArray<IndexType>,
519) -> PrimitiveArray<IndexType> {
520 let dummy = IndexType::Native::ZERO;
521 let normalized = indices.iter().map(|idx| idx.unwrap_or(dummy));
522 PrimitiveArray::from_iter_values(normalized)
523}
524
525#[derive(Clone, Debug, Default)]
527pub struct TakeOptions {
528 pub check_bounds: bool,
532}
533
534fn take_primitive<T, I, const VALIDATE_INDICES: bool>(
544 values: &PrimitiveArray<T>,
545 indices: &PrimitiveArray<I>,
546) -> Result<PrimitiveArray<T>, ArrowError>
547where
548 T: ArrowPrimitiveType,
549 I: ArrowPrimitiveType,
550{
551 let values_buf = take_native::<_, _, VALIDATE_INDICES>(values.values(), indices);
552 let nulls = take_nulls::<_, VALIDATE_INDICES>(values.nulls(), indices);
553 Ok(PrimitiveArray::try_new(values_buf, nulls)?.with_data_type(values.data_type().clone()))
554}
555
556#[inline(never)]
557fn take_nulls<I: ArrowPrimitiveType, const VALIDATE_INDICES: bool>(
558 values: Option<&NullBuffer>,
559 indices: &PrimitiveArray<I>,
560) -> Option<NullBuffer> {
561 match values.filter(|n| n.null_count() > 0) {
562 Some(n) => NullBuffer::from_unsliced_buffer(
563 take_bits::<_, VALIDATE_INDICES>(n.inner(), indices).into_inner(),
564 indices.len(),
565 ),
566 None => indices.nulls().cloned(),
567 }
568}
569
570#[inline(never)]
571fn take_native<T: ArrowNativeType, I: ArrowPrimitiveType, const VALIDATE_INDICES: bool>(
572 values: &[T],
573 indices: &PrimitiveArray<I>,
574) -> ScalarBuffer<T> {
575 match indices.nulls().filter(|n| n.null_count() > 0) {
576 Some(n) => indices
577 .values()
578 .iter()
579 .enumerate()
580 .map(|(idx, index)| match values.get(index.as_usize()) {
581 Some(v) => *v,
582 None => match unsafe { n.inner().value_unchecked(idx) } {
584 false => T::default(),
585 true => panic!("Out-of-bounds index {index:?}"),
586 },
587 })
588 .collect(),
589 None => {
590 if VALIDATE_INDICES {
591 indices
592 .values()
593 .iter()
594 .map(|index| values[index.as_usize()])
595 .collect()
596 } else {
597 indices
598 .values()
599 .iter()
600 .map(|index| {
601 unsafe { *values.get_unchecked(index.as_usize()) }
603 })
604 .collect()
605 }
606 }
607 }
608}
609
610#[inline(always)]
622unsafe fn copy_bit_if_set(src: *const u8, src_bit_idx: usize, dst: *mut u8, dst_bit_idx: usize) {
623 unsafe {
624 if bit_util::get_bit_raw(src, src_bit_idx) {
625 bit_util::set_bit_raw(dst, dst_bit_idx);
626 }
627 }
628}
629
630#[inline(always)]
641unsafe fn pack_bit(src: *const u8, bit_idx: usize, out_pos: usize) -> u8 {
642 let byte = unsafe { *src.add(bit_idx >> 3) }; ((byte >> (bit_idx & 7)) & 1) << out_pos }
645
646#[inline(never)]
647fn take_bits<I: ArrowPrimitiveType, const VALIDATE_INDICES: bool>(
648 values: &BooleanBuffer,
649 indices: &PrimitiveArray<I>,
650) -> BooleanBuffer {
651 let len = indices.len();
652 let src_offset = values.offset();
653 let src_ptr = values.values().as_ptr();
654 let out_bytes = len.div_ceil(8);
655
656 match indices.nulls().filter(|nulls| nulls.null_count() > 0) {
657 Some(index_nulls) => {
658 let mut output = vec![0u8; out_bytes];
659 let out_ptr = output.as_mut_ptr();
660 index_nulls.valid_indices().for_each(|valid_idx| {
661 let index_val = unsafe { indices.value_unchecked(valid_idx) }.as_usize();
663 if VALIDATE_INDICES {
664 if values.value(index_val) {
665 unsafe { bit_util::set_bit_raw(out_ptr, valid_idx) };
667 }
668 } else {
669 unsafe { copy_bit_if_set(src_ptr, index_val + src_offset, out_ptr, valid_idx) };
671 }
672 });
673 BooleanBuffer::new(Buffer::from(output), 0, len)
674 }
675 None => {
676 let mut output = vec![0u8; out_bytes];
679 let out_slice = output.as_mut_slice();
680 let full_bytes = len / 8;
681
682 for (byte_idx, out_byte) in out_slice.iter_mut().enumerate().take(full_bytes) {
683 let base = byte_idx * 8;
684 let mut byte = 0u8;
685 for bit in 0..8usize {
686 let index_val = unsafe { indices.value_unchecked(base + bit) }.as_usize();
689 if VALIDATE_INDICES {
690 byte |= (values.value(index_val) as u8) << bit;
691 } else {
692 byte |= unsafe { pack_bit(src_ptr, index_val + src_offset, bit) };
694 }
695 }
696 *out_byte = byte;
697 }
698 if full_bytes < out_bytes {
700 let base = full_bytes * 8;
701 let mut byte = 0u8;
702 for bit in 0..(len - base) {
703 let index_val = unsafe { indices.value_unchecked(base + bit) }.as_usize();
706 if VALIDATE_INDICES {
707 byte |= (values.value(index_val) as u8) << bit;
708 } else {
709 byte |= unsafe { pack_bit(src_ptr, index_val + src_offset, bit) };
711 }
712 }
713 out_slice[full_bytes] = byte;
714 }
715 BooleanBuffer::new(Buffer::from(output), 0, len)
716 }
717 }
718}
719
720#[inline(never)]
723fn take_bits_with_validity<I: ArrowPrimitiveType, const VALIDATE_INDICES: bool>(
724 values: &BooleanBuffer,
725 validity: &BooleanBuffer,
726 indices: &PrimitiveArray<I>,
727) -> (BooleanBuffer, Option<NullBuffer>) {
728 let len = indices.len();
729 let value_bit_offset = values.offset();
730 let validity_bit_offset = validity.offset();
731 let value_data_ptr = values.values().as_ptr();
732 let validity_data_ptr = validity.values().as_ptr();
733 let out_bytes = len.div_ceil(8);
734
735 let mut value_out = vec![0u8; out_bytes];
736 let mut validity_out = vec![0u8; out_bytes];
737
738 match indices.nulls().filter(|nulls| nulls.null_count() > 0) {
739 Some(index_nulls) => {
740 let value_out_ptr = value_out.as_mut_ptr();
741 let validity_out_ptr = validity_out.as_mut_ptr();
742 for out_pos in index_nulls.valid_indices() {
743 let src_idx = unsafe { indices.value_unchecked(out_pos) }.as_usize();
745 if VALIDATE_INDICES {
746 if values.value(src_idx) {
747 unsafe { bit_util::set_bit_raw(value_out_ptr, out_pos) };
749 }
750 if validity.value(src_idx) {
751 unsafe { bit_util::set_bit_raw(validity_out_ptr, out_pos) };
753 }
754 } else {
755 unsafe {
757 copy_bit_if_set(
758 value_data_ptr,
759 src_idx + value_bit_offset,
760 value_out_ptr,
761 out_pos,
762 );
763 copy_bit_if_set(
764 validity_data_ptr,
765 src_idx + validity_bit_offset,
766 validity_out_ptr,
767 out_pos,
768 );
769 }
770 }
771 }
772 }
773 None => {
774 let value_out_slice = value_out.as_mut_slice();
775 let validity_out_slice = validity_out.as_mut_slice();
776 let full_bytes = len / 8;
777
778 for (byte_idx, (value_out_byte, validity_out_byte)) in value_out_slice
779 .iter_mut()
780 .zip(validity_out_slice.iter_mut())
781 .enumerate()
782 .take(full_bytes)
783 {
784 let bit_base = byte_idx * 8;
785 let mut packed_values = 0u8;
786 let mut packed_validity = 0u8;
787 for bit_pos in 0..8usize {
788 let src_idx = unsafe { indices.value_unchecked(bit_base + bit_pos) }.as_usize();
790 if VALIDATE_INDICES {
791 packed_values |= (values.value(src_idx) as u8) << bit_pos;
792 packed_validity |= (validity.value(src_idx) as u8) << bit_pos;
793 } else {
794 packed_values |= unsafe {
796 pack_bit(value_data_ptr, src_idx + value_bit_offset, bit_pos)
797 };
798 packed_validity |= unsafe {
799 pack_bit(validity_data_ptr, src_idx + validity_bit_offset, bit_pos)
800 };
801 }
802 }
803 *value_out_byte = packed_values;
804 *validity_out_byte = packed_validity;
805 }
806 if full_bytes < out_bytes {
808 let bit_base = full_bytes * 8;
809 let mut packed_values = 0u8;
810 let mut packed_validity = 0u8;
811 for bit_pos in 0..(len - bit_base) {
812 let src_idx = unsafe { indices.value_unchecked(bit_base + bit_pos) }.as_usize();
814 if VALIDATE_INDICES {
815 packed_values |= (values.value(src_idx) as u8) << bit_pos;
816 packed_validity |= (validity.value(src_idx) as u8) << bit_pos;
817 } else {
818 packed_values |= unsafe {
820 pack_bit(value_data_ptr, src_idx + value_bit_offset, bit_pos)
821 };
822 packed_validity |= unsafe {
823 pack_bit(validity_data_ptr, src_idx + validity_bit_offset, bit_pos)
824 };
825 }
826 }
827 value_out_slice[full_bytes] = packed_values;
828 validity_out_slice[full_bytes] = packed_validity;
829 }
830 }
831 }
832
833 let value_buf_out = BooleanBuffer::new(Buffer::from(value_out), 0, len);
834 let validity_buf_out = NullBuffer::from_unsliced_buffer(validity_out, len);
835 (value_buf_out, validity_buf_out)
836}
837
838fn take_boolean<IndexType: ArrowPrimitiveType, const VALIDATE_INDICES: bool>(
840 array: &BooleanArray,
841 indices: &PrimitiveArray<IndexType>,
842) -> BooleanArray {
843 let bits = array.values();
844 match array.nulls().filter(|n| n.null_count() > 0) {
845 Some(array_nulls) => {
846 let (val_buf, null_buf) =
847 take_bits_with_validity::<_, VALIDATE_INDICES>(bits, array_nulls.inner(), indices);
848 BooleanArray::new(val_buf, null_buf)
849 }
850 None => {
851 let val_buf = take_bits::<_, VALIDATE_INDICES>(bits, indices);
852 let null_buf = take_nulls::<_, VALIDATE_INDICES>(None, indices);
853 BooleanArray::new(val_buf, null_buf)
854 }
855 }
856}
857
858fn take_bytes<T: ByteArrayType, IndexType: ArrowPrimitiveType, const VALIDATE_INDICES: bool>(
860 array: &GenericByteArray<T>,
861 indices: &PrimitiveArray<IndexType>,
862) -> Result<GenericByteArray<T>, ArrowError> {
863 let mut values: Vec<u8> = Vec::new();
864 let mut offsets = Vec::with_capacity(indices.len() + 1);
865 offsets.push(T::Offset::default());
866
867 let input_offsets = array.value_offsets();
868 let mut capacity = 0;
869 let nulls = take_nulls::<_, VALIDATE_INDICES>(array.nulls(), indices);
870
871 match nulls.as_ref().filter(|n| n.null_count() > 0) {
873 None => {
875 for index in indices.values() {
876 let index = index.as_usize();
877 let start = input_offsets[index].as_usize();
878 let end = input_offsets[index + 1].as_usize();
879 capacity += end - start;
880 offsets.push(
881 T::Offset::from_usize(capacity)
882 .ok_or_else(|| ArrowError::OffsetOverflowError(capacity))?,
883 );
884 }
885
886 values.reserve(capacity);
887
888 let dst = values.spare_capacity_mut();
889 debug_assert!(dst.len() >= capacity);
890 let mut offset = 0;
891
892 for index in indices.values() {
893 unsafe {
896 let data: &[u8] = array.value_unchecked(index.as_usize()).as_ref();
897 std::ptr::copy_nonoverlapping(
898 data.as_ptr(),
899 dst.get_unchecked_mut(offset..).as_mut_ptr().cast::<u8>(),
900 data.len(),
901 );
902 offset += data.len();
903 }
904 }
905
906 unsafe {
908 values.set_len(capacity);
909 }
910 }
911 Some(output_nulls) => {
913 let mut source_ranges = Vec::with_capacity(indices.len() - output_nulls.null_count());
914 let mut last_filled = 0;
915
916 offsets.resize(indices.len() + 1, T::Offset::default());
918
919 for i in output_nulls.valid_indices() {
921 let current_offset = T::Offset::from_usize(capacity)
922 .ok_or_else(|| ArrowError::OffsetOverflowError(capacity))?;
923 if last_filled < i {
925 offsets[last_filled + 1..=i].fill(current_offset);
926 }
927
928 let index = unsafe { indices.value_unchecked(i) }.as_usize();
930 let start = input_offsets[index].as_usize();
931 let end = input_offsets[index + 1].as_usize();
932 capacity += end - start;
933 offsets[i + 1] = T::Offset::from_usize(capacity)
934 .ok_or_else(|| ArrowError::OffsetOverflowError(capacity))?;
935
936 source_ranges.push((start, end));
937 last_filled = i + 1;
938 }
939
940 let final_offset = T::Offset::from_usize(capacity)
942 .ok_or_else(|| ArrowError::OffsetOverflowError(capacity))?;
943 offsets[last_filled + 1..].fill(final_offset);
944 values.reserve(capacity);
946 debug_assert_eq!(
947 source_ranges.iter().map(|(s, e)| e - s).sum::<usize>(),
948 capacity,
949 "capacity must equal total bytes across all ranges"
950 );
951
952 let src = array.value_data();
953 let src = src.as_ptr();
954 let dst = values.spare_capacity_mut();
955 debug_assert!(dst.len() >= capacity);
956
957 let mut offset = 0;
958
959 for (start, end) in source_ranges {
960 let value_len = end - start;
961 unsafe {
965 std::ptr::copy_nonoverlapping(
966 src.add(start),
967 dst.get_unchecked_mut(offset..).as_mut_ptr().cast::<u8>(),
968 value_len,
969 );
970 offset += value_len;
971 }
972 }
973 unsafe { values.set_len(capacity) };
976 }
977 }
978
979 let array = unsafe {
982 let offsets = OffsetBuffer::new_unchecked(offsets.into());
983 GenericByteArray::<T>::new_unchecked(offsets, values.into(), nulls)
984 };
985
986 Ok(array)
987}
988
989fn take_byte_view<T: ByteViewType, IndexType: ArrowPrimitiveType, const VALIDATE_INDICES: bool>(
991 array: &GenericByteViewArray<T>,
992 indices: &PrimitiveArray<IndexType>,
993) -> Result<GenericByteViewArray<T>, ArrowError> {
994 let new_views = take_native::<_, _, VALIDATE_INDICES>(array.views(), indices);
995 let new_nulls = take_nulls::<_, VALIDATE_INDICES>(array.nulls(), indices);
996 let buffers = Arc::clone(array.data_buffers());
997 Ok(unsafe { GenericByteViewArray::new_unchecked(new_views, buffers, new_nulls) })
999}
1000
1001fn take_list<IndexType, OffsetType, const VALIDATE_INDICES: bool>(
1006 values: &GenericListArray<OffsetType::Native>,
1007 indices: &PrimitiveArray<IndexType>,
1008) -> Result<GenericListArray<OffsetType::Native>, ArrowError>
1009where
1010 IndexType: ArrowPrimitiveType,
1011 OffsetType: ArrowPrimitiveType,
1012 OffsetType::Native: OffsetSizeTrait,
1013 PrimitiveArray<OffsetType>: From<Vec<OffsetType::Native>>,
1014{
1015 let src_offsets = values.value_offsets();
1016 let child_data = values.values().to_data();
1017 let visible_child_len = (values.offsets().last() - values.offsets().first()).as_usize();
1019 let estimated_child_len = visible_child_len
1021 .checked_div(values.len())
1022 .map_or(0, |avg| avg.saturating_mul(indices.len()));
1023 let nulls = take_nulls::<_, VALIDATE_INDICES>(values.nulls(), indices);
1024
1025 let mut dst_offsets = Vec::with_capacity(indices.len() + 1);
1026 dst_offsets.push(OffsetType::Native::zero());
1027
1028 let field = values.value_field().clone();
1029
1030 if child_data.null_count() == 0
1031 && let Some(bytes_per_value) = child_data.data_type().primitive_width()
1032 {
1033 let values_buf = &child_data.buffers()[0];
1034 let child_buf_offset = child_data.offset() * bytes_per_value;
1035
1036 let capacity = estimated_child_len.saturating_mul(bytes_per_value);
1037 let mut dst_buf = MutableBuffer::try_with_capacity(capacity)
1038 .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
1039
1040 let mut child_len = OffsetType::Native::zero();
1041
1042 match nulls.as_ref().filter(|n| n.null_count() > 0) {
1043 None => {
1044 for &idx in indices.values() {
1045 let row = idx.as_usize();
1046 let start = child_buf_offset + src_offsets[row].as_usize() * bytes_per_value;
1047 let end = child_buf_offset + src_offsets[row + 1].as_usize() * bytes_per_value;
1048 dst_buf
1049 .try_extend_from_slice(&values_buf[start..end])
1050 .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
1051 child_len = child_len
1052 .checked_add(&(src_offsets[row + 1] - src_offsets[row]))
1053 .ok_or_else(|| ArrowError::OffsetOverflowError(child_len.as_usize()))?;
1054 dst_offsets.push(child_len);
1055 }
1056 }
1057 Some(valid) => {
1058 let mut prev = 0;
1059 for vidx in valid.valid_indices() {
1060 if prev < vidx {
1062 dst_offsets.extend(std::iter::repeat_n(child_len, vidx - prev));
1063 }
1064 let row = unsafe { indices.value_unchecked(vidx) }.as_usize();
1066 let (start, end) = if VALIDATE_INDICES {
1067 (
1068 child_buf_offset + src_offsets[row].as_usize() * bytes_per_value,
1069 child_buf_offset + src_offsets[row + 1].as_usize() * bytes_per_value,
1070 )
1071 } else {
1072 unsafe {
1074 (
1075 child_buf_offset
1076 + src_offsets.get_unchecked(row).as_usize() * bytes_per_value,
1077 child_buf_offset
1078 + src_offsets.get_unchecked(row + 1).as_usize()
1079 * bytes_per_value,
1080 )
1081 }
1082 };
1083 dst_buf
1084 .try_extend_from_slice(&values_buf[start..end])
1085 .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
1086 child_len = child_len
1087 .checked_add(&(src_offsets[row + 1] - src_offsets[row]))
1088 .ok_or_else(|| ArrowError::OffsetOverflowError(child_len.as_usize()))?;
1089 dst_offsets.push(child_len);
1090 prev = vidx + 1;
1091 }
1092 dst_offsets.extend(std::iter::repeat_n(child_len, indices.len() - prev));
1093 }
1094 }
1095
1096 debug_assert_eq!(
1097 dst_offsets.len(),
1098 indices.len() + 1,
1099 "New offsets was filled under/over the expected capacity"
1100 );
1101
1102 let child = make_array(unsafe {
1105 ArrayData::builder(child_data.data_type().clone())
1106 .len(child_len.as_usize())
1107 .add_buffer(dst_buf.into())
1108 .build_unchecked()
1109 });
1110 let offsets = unsafe { OffsetBuffer::new_unchecked(ScalarBuffer::from(dst_offsets)) };
1112 return GenericListArray::<OffsetType::Native>::try_new(field, offsets, child, nulls);
1113 }
1114
1115 let mut mutable = MutableArrayData::try_new(
1116 vec![&child_data],
1117 child_data.null_count() > 0,
1118 estimated_child_len,
1119 )?;
1120
1121 match nulls.as_ref().filter(|n| n.null_count() > 0) {
1122 None => {
1123 for idx in indices.values() {
1124 let row = idx.as_usize();
1125 mutable.try_extend(
1126 0,
1127 src_offsets[row].as_usize(),
1128 src_offsets[row + 1].as_usize(),
1129 )?;
1130 dst_offsets.push(
1131 OffsetType::Native::from_usize(mutable.len())
1132 .ok_or_else(|| ArrowError::OffsetOverflowError(mutable.len()))?,
1133 );
1134 }
1135 }
1136 Some(valid) => {
1137 let mut last = 0;
1138 for i in valid.valid_indices() {
1139 let current = OffsetType::Native::from_usize(mutable.len())
1140 .ok_or_else(|| ArrowError::OffsetOverflowError(mutable.len()))?;
1141 if last < i {
1142 dst_offsets.extend(std::iter::repeat_n(current, i - last));
1143 }
1144 let row = unsafe { indices.value_unchecked(i) }.as_usize();
1146 let (start, end) = if VALIDATE_INDICES {
1147 (src_offsets[row].as_usize(), src_offsets[row + 1].as_usize())
1148 } else {
1149 unsafe {
1151 (
1152 src_offsets.get_unchecked(row).as_usize(),
1153 src_offsets.get_unchecked(row + 1).as_usize(),
1154 )
1155 }
1156 };
1157 mutable.try_extend(0, start, end)?;
1158 dst_offsets.push(
1159 OffsetType::Native::from_usize(mutable.len())
1160 .ok_or_else(|| ArrowError::OffsetOverflowError(mutable.len()))?,
1161 );
1162 last = i + 1;
1163 }
1164 let final_offset = OffsetType::Native::from_usize(mutable.len())
1166 .ok_or_else(|| ArrowError::OffsetOverflowError(mutable.len()))?;
1167 dst_offsets.extend(std::iter::repeat_n(final_offset, indices.len() - last));
1168 }
1169 }
1170
1171 debug_assert_eq!(dst_offsets.len(), indices.len() + 1);
1172
1173 let offsets = unsafe { OffsetBuffer::new_unchecked(ScalarBuffer::from(dst_offsets)) };
1175 let child = make_array(mutable.freeze());
1176 GenericListArray::<OffsetType::Native>::try_new(field, offsets, child, nulls)
1177}
1178
1179fn take_list_view<IndexType, OffsetType, const VALIDATE_INDICES: bool>(
1180 values: &GenericListViewArray<OffsetType::Native>,
1181 indices: &PrimitiveArray<IndexType>,
1182) -> Result<GenericListViewArray<OffsetType::Native>, ArrowError>
1183where
1184 IndexType: ArrowPrimitiveType,
1185 OffsetType: ArrowPrimitiveType,
1186 OffsetType::Native: OffsetSizeTrait,
1187{
1188 let taken_offsets = take_native::<_, _, VALIDATE_INDICES>(values.offsets(), indices);
1189 let taken_sizes = take_native::<_, _, VALIDATE_INDICES>(values.sizes(), indices);
1190 let nulls = take_nulls::<_, VALIDATE_INDICES>(values.nulls(), indices);
1191
1192 let field = match values.data_type() {
1193 DataType::ListView(field) | DataType::LargeListView(field) => field.clone(),
1194 d => unreachable!("take_list_view called with non-list-view data type {d}"),
1195 };
1196
1197 Ok(unsafe {
1200 GenericListViewArray::<OffsetType::Native>::new_unchecked(
1201 field,
1202 taken_offsets,
1203 taken_sizes,
1204 Arc::clone(values.values()),
1205 nulls,
1206 )
1207 })
1208}
1209
1210fn take_fixed_size_list<IndexType: ArrowPrimitiveType, const VALIDATE_INDICES: bool>(
1216 values: &FixedSizeListArray,
1217 indices: &PrimitiveArray<IndexType>,
1218 length: <UInt32Type as ArrowPrimitiveType>::Native,
1219) -> Result<FixedSizeListArray, ArrowError> {
1220 let field = values.value_field();
1221 let child = values.values();
1222 let nulls = take_nulls::<_, VALIDATE_INDICES>(values.nulls(), indices);
1223
1224 let taken_child = if child.null_count() == 0
1226 && let Some(element_size) = child.data_type().primitive_width()
1227 {
1228 take_fixed_size_list_primitive(
1229 child,
1230 indices,
1231 length as usize,
1232 element_size,
1233 nulls.as_ref(),
1234 )?
1235 } else {
1236 let list_indices = take_value_indices_from_fixed_size_list(values, indices, length)?;
1237 take_impl::<UInt32Type, VALIDATE_INDICES>(child.as_ref(), &list_indices)?
1238 };
1239
1240 FixedSizeListArray::try_new_with_length(
1241 field.clone(),
1242 length as i32,
1243 taken_child,
1244 nulls,
1245 indices.len(),
1246 )
1247}
1248
1249#[inline(never)]
1250fn take_fixed_size_list_primitive<IndexType: ArrowPrimitiveType>(
1251 child: &ArrayRef,
1252 indices: &PrimitiveArray<IndexType>,
1253 list_size: usize,
1254 element_size: usize,
1255 taken_row_nulls: Option<&NullBuffer>,
1256) -> Result<ArrayRef, ArrowError> {
1257 let row_bytes = list_size
1258 .checked_mul(element_size)
1259 .ok_or_else(|| ArrowError::MemoryError("take output size overflow".into()))?;
1260 let child_data = child.to_data();
1261 let src = child_data.buffers()[0].as_slice();
1262 let child_byte_offset = child_data.offset() * element_size;
1263
1264 let out_len = indices
1265 .len()
1266 .checked_mul(list_size)
1267 .ok_or_else(|| ArrowError::MemoryError("take output size overflow".into()))?;
1268 let out_byte_len = indices
1269 .len()
1270 .checked_mul(row_bytes)
1271 .ok_or_else(|| ArrowError::MemoryError("take output size overflow".into()))?;
1272
1273 let mut out = MutableBuffer::try_from_len_zeroed(out_byte_len)
1274 .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
1275 let out_slice = out.as_slice_mut();
1276
1277 if indices.null_count() == 0 {
1278 for (out_row, index) in indices.values().iter().enumerate() {
1279 let src_start = child_byte_offset + index.as_usize() * row_bytes;
1280 out_slice[out_row * row_bytes..(out_row + 1) * row_bytes]
1281 .copy_from_slice(&src[src_start..src_start + row_bytes]);
1282 }
1283 } else {
1284 for (out_row, index) in indices.values().iter().enumerate() {
1285 if indices.is_valid(out_row) {
1286 let src_start = child_byte_offset + index.as_usize() * row_bytes;
1287 out_slice[out_row * row_bytes..(out_row + 1) * row_bytes]
1288 .copy_from_slice(&src[src_start..src_start + row_bytes]);
1289 }
1290 }
1291 }
1292 let child_null_buf = taken_row_nulls
1294 .map(|n| {
1295 n.try_expand(list_size)
1296 .map(|n| n.buffer().clone())
1297 .map_err(|e| ArrowError::MemoryError(e.to_string()))
1298 })
1299 .transpose()?;
1300
1301 let array_data = unsafe {
1308 ArrayData::builder(child.data_type().clone())
1309 .len(out_len)
1310 .add_buffer(out.into())
1311 .null_bit_buffer(child_null_buf)
1312 .build_unchecked()
1313 };
1314 Ok(make_array(array_data))
1315}
1316
1317fn take_fixed_size_binary<IndexType: ArrowPrimitiveType, const VALIDATE_INDICES: bool>(
1323 values: &FixedSizeBinaryArray,
1324 indices: &PrimitiveArray<IndexType>,
1325 size: i32,
1326) -> Result<FixedSizeBinaryArray, ArrowError> {
1327 let size_usize = usize::try_from(size).map_err(|_| {
1328 ArrowError::InvalidArgumentError(format!("Cannot convert size '{size}' to usize"))
1329 })?;
1330
1331 let result_buffer = match size_usize {
1332 1 => take_fixed_size::<IndexType, 1>(values.values(), indices),
1333 2 => take_fixed_size::<IndexType, 2>(values.values(), indices),
1334 4 => take_fixed_size::<IndexType, 4>(values.values(), indices),
1335 8 => take_fixed_size::<IndexType, 8>(values.values(), indices),
1336 16 => take_fixed_size::<IndexType, 16>(values.values(), indices),
1337 _ => take_fixed_size_binary_buffer_dynamic_length(values, indices, size_usize),
1338 };
1339
1340 let value_nulls = take_nulls::<_, VALIDATE_INDICES>(values.nulls(), indices);
1341 let final_nulls = NullBuffer::union(value_nulls.as_ref(), indices.nulls());
1342
1343 return FixedSizeBinaryArray::try_new_with_len(size, result_buffer, final_nulls, indices.len());
1344
1345 #[inline(never)]
1347 fn take_fixed_size_binary_buffer_dynamic_length<IndexType: ArrowPrimitiveType>(
1348 values: &FixedSizeBinaryArray,
1349 indices: &PrimitiveArray<IndexType>,
1350 size_usize: usize,
1351 ) -> Buffer {
1352 let values_buffer = values.values().as_slice();
1353 let mut output = Vec::with_capacity(indices.len() * size_usize);
1354
1355 if indices.null_count() == 0 {
1356 let array_iter = indices.values().iter().map(|idx| {
1357 let offset = idx.as_usize() * size_usize;
1358 &values_buffer[offset..offset + size_usize]
1359 });
1360 for slice in array_iter {
1361 output.extend_from_slice(slice);
1362 }
1363 } else {
1364 let array_iter = indices.iter().map(|idx| {
1367 idx.map(|idx| {
1368 let offset = idx.as_usize() * size_usize;
1369 &values_buffer[offset..offset + size_usize]
1370 })
1371 });
1372 for slice in array_iter {
1373 match slice {
1374 None => output.resize(output.len() + size_usize, 0),
1375 Some(slice) => output.extend_from_slice(slice),
1376 }
1377 }
1378 }
1379
1380 output.into()
1381 }
1382}
1383
1384fn take_fixed_size<IndexType: ArrowPrimitiveType, const N: usize>(
1397 buffer: &Buffer,
1398 indices: &PrimitiveArray<IndexType>,
1399) -> Buffer {
1400 assert_eq!(
1401 buffer.len() % N,
1402 0,
1403 "Invalid array length in take_fixed_size"
1404 );
1405
1406 let ptr = buffer.as_ptr();
1407 let chunk_ptr = ptr.cast::<[u8; N]>();
1408 let chunk_len = buffer.len() / N;
1409 let buffer: &[[u8; N]] = unsafe {
1410 std::slice::from_raw_parts(chunk_ptr, chunk_len)
1413 };
1414
1415 let result_buffer = match indices.nulls().filter(|n| n.null_count() > 0) {
1416 Some(n) => indices
1417 .values()
1418 .iter()
1419 .enumerate()
1420 .map(|(idx, index)| match buffer.get(index.as_usize()) {
1421 Some(v) => *v,
1422 None => match unsafe { n.inner().value_unchecked(idx) } {
1424 false => [0u8; N],
1425 true => panic!("Out-of-bounds index {index:?}"),
1426 },
1427 })
1428 .collect::<Vec<_>>(),
1429 None => indices
1430 .values()
1431 .iter()
1432 .map(|index| buffer[index.as_usize()])
1433 .collect::<Vec<_>>(),
1434 };
1435
1436 let mut vec = ManuallyDrop::new(result_buffer); let ptr = vec.as_mut_ptr();
1438 let len = vec.len();
1439 let cap = vec.capacity();
1440 let result_buffer = unsafe {
1441 Vec::from_raw_parts(ptr.cast::<u8>(), len * N, cap * N)
1443 };
1444
1445 Buffer::from_vec(result_buffer)
1446}
1447
1448fn take_dict<T: ArrowDictionaryKeyType, I: ArrowPrimitiveType, const VALIDATE_INDICES: bool>(
1453 values: &DictionaryArray<T>,
1454 indices: &PrimitiveArray<I>,
1455) -> Result<DictionaryArray<T>, ArrowError> {
1456 let new_keys = take_primitive::<_, _, VALIDATE_INDICES>(values.keys(), indices)?;
1457 Ok(unsafe { DictionaryArray::new_unchecked(new_keys, values.values().clone()) })
1458}
1459
1460fn take_run<T: RunEndIndexType, I: ArrowPrimitiveType>(
1471 run_array: &RunArray<T>,
1472 logical_indices: &PrimitiveArray<I>,
1473) -> Result<RunArray<T>, ArrowError> {
1474 if logical_indices.null_count() > 0 && !run_array.values_field().is_nullable() {
1475 return Err(ArrowError::ComputeError(
1476 "Cannot take null indices from a RunEndEncoded array with a non-nullable values field"
1477 .into(),
1478 ));
1479 }
1480
1481 let physical_indices = physical_indices_for_take(run_array, logical_indices)?;
1482
1483 let mut new_run_ends = Vec::with_capacity(1);
1487 let mut take_value_indices = Vec::with_capacity(1);
1488 let mut take_value_is_valid = NullBufferBuilder::new(1);
1489
1490 let values_cmp = make_comparator(
1491 run_array.values().as_ref(),
1492 run_array.values().as_ref(),
1493 SortOptions::default(),
1494 )?;
1495
1496 for ix in 1..physical_indices.len() {
1497 let prev_idx = physical_indices[ix - 1];
1498 let cur_idx = physical_indices[ix];
1499 if is_new_run_take(run_array.values().as_ref(), prev_idx, cur_idx, &values_cmp) {
1500 let index = I::Native::from_usize(prev_idx.unwrap_or_default()).unwrap();
1502 take_value_indices.push(index);
1503 take_value_is_valid
1504 .append(prev_idx.is_some_and(|idx| run_array.values().is_valid(idx)));
1505 new_run_ends.push(T::Native::from_usize(ix).unwrap());
1506 }
1507 }
1508 let last = physical_indices[physical_indices.len() - 1];
1509 let index = I::Native::from_usize(last.unwrap_or_default()).unwrap();
1511 take_value_indices.push(index);
1512 take_value_is_valid.append(last.is_some_and(|idx| run_array.values().is_valid(idx)));
1513 new_run_ends.push(T::Native::from_usize(physical_indices.len()).unwrap());
1514
1515 let run_ends = unsafe {
1517 RunEndBuffer::new_unchecked(ScalarBuffer::from(new_run_ends), 0, physical_indices.len())
1518 };
1519
1520 let nulls = take_value_is_valid.finish();
1521 let take_value_indices =
1522 PrimitiveArray::<I>::new(ScalarBuffer::from(take_value_indices), nulls);
1523
1524 let new_values = take(run_array.values(), &take_value_indices, None)?;
1525
1526 Ok(
1528 unsafe {
1529 RunArray::<T>::new_unchecked(run_array.data_type().clone(), run_ends, new_values)
1530 },
1531 )
1532}
1533
1534fn physical_indices_for_take<T: RunEndIndexType, I: ArrowPrimitiveType>(
1540 run_array: &RunArray<T>,
1541 logical_indices: &PrimitiveArray<I>,
1542) -> Result<Vec<Option<usize>>, ArrowError> {
1543 if logical_indices.null_count() == 0 {
1544 return Ok(run_array
1545 .get_physical_indices(logical_indices.values())?
1546 .into_iter()
1547 .map(Some)
1548 .collect());
1549 }
1550
1551 let valid_logical: Vec<_> = logical_indices.iter().flatten().collect();
1552
1553 let valid_physical = if valid_logical.is_empty() {
1554 Vec::new()
1555 } else {
1556 run_array.get_physical_indices(&valid_logical)?
1557 };
1558
1559 let mut valid_physical = valid_physical.into_iter();
1560 Ok(logical_indices
1561 .iter()
1562 .map(|index| index.map(|_| valid_physical.next().unwrap()))
1563 .collect())
1564}
1565
1566fn is_new_run_take(
1567 values: &dyn Array,
1568 prev_idx: Option<usize>,
1569 cur_idx: Option<usize>,
1570 values_cmp: &arrow_cmp::DynComparator,
1571) -> bool {
1572 let prev_valid = prev_idx.is_some_and(|idx| values.is_valid(idx));
1573 let cur_valid = cur_idx.is_some_and(|idx| values.is_valid(idx));
1574 match (prev_valid, cur_valid) {
1575 (false, false) => false,
1576 (true, true) => {
1577 let prev = prev_idx.unwrap();
1578 let cur = cur_idx.unwrap();
1579 prev != cur && values_cmp(cur, prev).is_ne()
1580 }
1581 _ => true,
1582 }
1583}
1584
1585fn take_value_indices_from_fixed_size_list<IndexType>(
1587 list: &FixedSizeListArray,
1588 indices: &PrimitiveArray<IndexType>,
1589 length: <UInt32Type as ArrowPrimitiveType>::Native,
1590) -> Result<PrimitiveArray<UInt32Type>, ArrowError>
1591where
1592 IndexType: ArrowPrimitiveType,
1593{
1594 let mut values = UInt32Builder::with_capacity(length as usize * indices.len());
1595
1596 for i in 0..indices.len() {
1597 if indices.is_valid(i) {
1598 let index = indices
1599 .value(i)
1600 .to_usize()
1601 .ok_or_else(|| ArrowError::ComputeError("Cast to usize failed".to_string()))?;
1602 let start = u32::try_from(list.value_offset_at(index)).map_err(|_| {
1603 ArrowError::ComputeError("FixedSizeList offset overflows u32".to_string())
1604 })?;
1605
1606 unsafe {
1608 values.append_trusted_len_iter(start..start + length);
1609 }
1610 } else {
1611 values.append_nulls(length as usize);
1612 }
1613 }
1614
1615 Ok(values.finish())
1616}
1617
1618trait ToIndices {
1621 type T: ArrowPrimitiveType;
1622
1623 fn to_indices(&self) -> PrimitiveArray<Self::T>;
1624}
1625
1626macro_rules! to_indices_reinterpret {
1627 ($t:ty, $o:ty) => {
1628 impl ToIndices for PrimitiveArray<$t> {
1629 type T = $o;
1630
1631 fn to_indices(&self) -> PrimitiveArray<$o> {
1632 let cast = ScalarBuffer::new(self.values().inner().clone(), 0, self.len());
1633 PrimitiveArray::new(cast, self.nulls().cloned())
1634 }
1635 }
1636 };
1637}
1638
1639macro_rules! to_indices_identity {
1640 ($t:ty) => {
1641 impl ToIndices for PrimitiveArray<$t> {
1642 type T = $t;
1643
1644 fn to_indices(&self) -> PrimitiveArray<$t> {
1645 self.clone()
1646 }
1647 }
1648 };
1649}
1650
1651macro_rules! to_indices_widening {
1652 ($t:ty, $o:ty) => {
1653 impl ToIndices for PrimitiveArray<$t> {
1654 type T = UInt32Type;
1655
1656 fn to_indices(&self) -> PrimitiveArray<$o> {
1657 let cast = self.values().iter().copied().map(|x| x as _).collect();
1658 PrimitiveArray::new(cast, self.nulls().cloned())
1659 }
1660 }
1661 };
1662}
1663
1664to_indices_widening!(UInt8Type, UInt32Type);
1665to_indices_widening!(Int8Type, UInt32Type);
1666
1667to_indices_widening!(UInt16Type, UInt32Type);
1668to_indices_widening!(Int16Type, UInt32Type);
1669
1670to_indices_identity!(UInt32Type);
1671to_indices_reinterpret!(Int32Type, UInt32Type);
1672
1673to_indices_identity!(UInt64Type);
1674to_indices_reinterpret!(Int64Type, UInt64Type);
1675
1676pub fn take_record_batch(
1721 record_batch: &RecordBatch,
1722 indices: &dyn Array,
1723) -> Result<RecordBatch, ArrowError> {
1724 downcast_integer_array!(
1725 indices => {
1726 let indices = indices.to_indices();
1727 check_bounds(record_batch.num_rows(), &indices)?;
1730 let columns = record_batch
1731 .columns()
1732 .iter()
1733 .map(|c| take_impl::<_, false>(c.as_ref(), &indices))
1734 .collect::<Result<Vec<_>, _>>()?;
1735 let options = RecordBatchOptions::new().with_row_count(Some(indices.len()));
1738 RecordBatch::try_new_with_options(record_batch.schema(), columns, &options)
1739 },
1740 d => Err(ArrowError::InvalidArgumentError(format!("Take only supported for integers, got {d:?}")))
1741 )
1742}
1743
1744#[cfg(test)]
1745mod tests {
1746 use super::*;
1747 use arrow_array::builder::*;
1748 use arrow_buffer::{IntervalDayTime, IntervalMonthDayNano};
1749 use arrow_schema::{Field, Fields, Schema, TimeUnit, UnionFields};
1750 use num_traits::ToPrimitive;
1751
1752 fn test_take_decimal_arrays(
1753 data: Vec<Option<i128>>,
1754 index: &UInt32Array,
1755 options: Option<TakeOptions>,
1756 expected_data: Vec<Option<i128>>,
1757 precision: &u8,
1758 scale: &i8,
1759 ) -> Result<(), ArrowError> {
1760 let output = data
1761 .into_iter()
1762 .collect::<Decimal128Array>()
1763 .with_precision_and_scale(*precision, *scale)
1764 .unwrap();
1765
1766 let expected = expected_data
1767 .into_iter()
1768 .collect::<Decimal128Array>()
1769 .with_precision_and_scale(*precision, *scale)
1770 .unwrap();
1771
1772 let expected = Arc::new(expected) as ArrayRef;
1773 let output = take(&output, index, options).unwrap();
1774 assert_eq!(&output, &expected);
1775 Ok(())
1776 }
1777
1778 fn test_take_boolean_arrays(
1779 data: Vec<Option<bool>>,
1780 index: &UInt32Array,
1781 options: Option<TakeOptions>,
1782 expected_data: Vec<Option<bool>>,
1783 ) {
1784 let output = BooleanArray::from(data);
1785 let expected = Arc::new(BooleanArray::from(expected_data)) as ArrayRef;
1786 let output = take(&output, index, options).unwrap();
1787 assert_eq!(&output, &expected)
1788 }
1789
1790 fn test_take_primitive_arrays<T>(
1791 data: Vec<Option<T::Native>>,
1792 index: &UInt32Array,
1793 options: Option<TakeOptions>,
1794 expected_data: Vec<Option<T::Native>>,
1795 ) -> Result<(), ArrowError>
1796 where
1797 T: ArrowPrimitiveType,
1798 PrimitiveArray<T>: From<Vec<Option<T::Native>>>,
1799 {
1800 let output = PrimitiveArray::<T>::from(data);
1801 let expected = Arc::new(PrimitiveArray::<T>::from(expected_data)) as ArrayRef;
1802 let output = take(&output, index, options)?;
1803 assert_eq!(&output, &expected);
1804 Ok(())
1805 }
1806
1807 fn test_take_primitive_arrays_non_null<T>(
1808 data: Vec<T::Native>,
1809 index: &UInt32Array,
1810 options: Option<TakeOptions>,
1811 expected_data: Vec<Option<T::Native>>,
1812 ) -> Result<(), ArrowError>
1813 where
1814 T: ArrowPrimitiveType,
1815 PrimitiveArray<T>: From<Vec<T::Native>>,
1816 PrimitiveArray<T>: From<Vec<Option<T::Native>>>,
1817 {
1818 let output = PrimitiveArray::<T>::from(data);
1819 let expected = Arc::new(PrimitiveArray::<T>::from(expected_data)) as ArrayRef;
1820 let output = take(&output, index, options)?;
1821 assert_eq!(&output, &expected);
1822 Ok(())
1823 }
1824
1825 fn test_take_impl_primitive_arrays<T, I>(
1826 data: Vec<Option<T::Native>>,
1827 index: &PrimitiveArray<I>,
1828 options: Option<TakeOptions>,
1829 expected_data: Vec<Option<T::Native>>,
1830 ) where
1831 T: ArrowPrimitiveType,
1832 PrimitiveArray<T>: From<Vec<Option<T::Native>>>,
1833 I: ArrowPrimitiveType,
1834 {
1835 let output = PrimitiveArray::<T>::from(data);
1836 let expected = PrimitiveArray::<T>::from(expected_data);
1837 let output = take(&output, index, options).unwrap();
1838 let output = output.as_any().downcast_ref::<PrimitiveArray<T>>().unwrap();
1839 assert_eq!(output, &expected)
1840 }
1841
1842 fn create_test_struct(values: Vec<Option<(Option<bool>, Option<i32>)>>) -> StructArray {
1844 let mut struct_builder = StructBuilder::new(
1845 Fields::from(vec![
1846 Field::new("a", DataType::Boolean, true),
1847 Field::new("b", DataType::Int32, true),
1848 ]),
1849 vec![
1850 Box::new(BooleanBuilder::with_capacity(values.len())),
1851 Box::new(Int32Builder::with_capacity(values.len())),
1852 ],
1853 );
1854
1855 for value in values {
1856 struct_builder
1857 .field_builder::<BooleanBuilder>(0)
1858 .unwrap()
1859 .append_option(value.and_then(|v| v.0));
1860 struct_builder
1861 .field_builder::<Int32Builder>(1)
1862 .unwrap()
1863 .append_option(value.and_then(|v| v.1));
1864 struct_builder.append(value.is_some());
1865 }
1866 struct_builder.finish()
1867 }
1868
1869 #[test]
1870 fn test_take_decimal128_non_null_indices() {
1871 let index = UInt32Array::from(vec![0, 5, 3, 1, 4, 2]);
1872 let precision: u8 = 10;
1873 let scale: i8 = 5;
1874 test_take_decimal_arrays(
1875 vec![None, Some(3), Some(5), Some(2), Some(3), None],
1876 &index,
1877 None,
1878 vec![None, None, Some(2), Some(3), Some(3), Some(5)],
1879 &precision,
1880 &scale,
1881 )
1882 .unwrap();
1883 }
1884
1885 #[test]
1886 fn test_take_decimal128() {
1887 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(3), Some(2)]);
1888 let precision: u8 = 10;
1889 let scale: i8 = 5;
1890 test_take_decimal_arrays(
1891 vec![Some(0), Some(1), Some(2), Some(3), Some(4)],
1892 &index,
1893 None,
1894 vec![Some(3), None, Some(1), Some(3), Some(2)],
1895 &precision,
1896 &scale,
1897 )
1898 .unwrap();
1899 }
1900
1901 #[test]
1902 fn test_take_primitive_non_null_indices() {
1903 let index = UInt32Array::from(vec![0, 5, 3, 1, 4, 2]);
1904 test_take_primitive_arrays::<Int8Type>(
1905 vec![None, Some(3), Some(5), Some(2), Some(3), None],
1906 &index,
1907 None,
1908 vec![None, None, Some(2), Some(3), Some(3), Some(5)],
1909 )
1910 .unwrap();
1911 }
1912
1913 #[test]
1914 fn test_take_primitive_non_null_values() {
1915 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(3), Some(2)]);
1916 test_take_primitive_arrays::<Int8Type>(
1917 vec![Some(0), Some(1), Some(2), Some(3), Some(4)],
1918 &index,
1919 None,
1920 vec![Some(3), None, Some(1), Some(3), Some(2)],
1921 )
1922 .unwrap();
1923 }
1924
1925 #[test]
1926 fn test_take_primitive_non_null() {
1927 let index = UInt32Array::from(vec![0, 5, 3, 1, 4, 2]);
1928 test_take_primitive_arrays::<Int8Type>(
1929 vec![Some(0), Some(3), Some(5), Some(2), Some(3), Some(1)],
1930 &index,
1931 None,
1932 vec![Some(0), Some(1), Some(2), Some(3), Some(3), Some(5)],
1933 )
1934 .unwrap();
1935 }
1936
1937 #[test]
1938 fn test_take_primitive_nullable_indices_non_null_values_with_offset() {
1939 let index = UInt32Array::from(vec![Some(0), Some(1), Some(2), Some(3), None, None]);
1940 let index = index.slice(2, 4);
1941 let index = index.as_any().downcast_ref::<UInt32Array>().unwrap();
1942
1943 assert_eq!(
1944 index,
1945 &UInt32Array::from(vec![Some(2), Some(3), None, None])
1946 );
1947
1948 test_take_primitive_arrays_non_null::<Int64Type>(
1949 vec![0, 10, 20, 30, 40, 50],
1950 index,
1951 None,
1952 vec![Some(20), Some(30), None, None],
1953 )
1954 .unwrap();
1955 }
1956
1957 #[test]
1958 fn test_take_primitive_nullable_indices_nullable_values_with_offset() {
1959 let index = UInt32Array::from(vec![Some(0), Some(1), Some(2), Some(3), None, None]);
1960 let index = index.slice(2, 4);
1961 let index = index.as_any().downcast_ref::<UInt32Array>().unwrap();
1962
1963 assert_eq!(
1964 index,
1965 &UInt32Array::from(vec![Some(2), Some(3), None, None])
1966 );
1967
1968 test_take_primitive_arrays::<Int64Type>(
1969 vec![None, None, Some(20), Some(30), Some(40), Some(50)],
1970 index,
1971 None,
1972 vec![Some(20), Some(30), None, None],
1973 )
1974 .unwrap();
1975 }
1976
1977 #[test]
1978 fn test_take_primitive() {
1979 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(3), Some(2)]);
1980
1981 test_take_primitive_arrays::<Int8Type>(
1983 vec![Some(0), None, Some(2), Some(3), None],
1984 &index,
1985 None,
1986 vec![Some(3), None, None, Some(3), Some(2)],
1987 )
1988 .unwrap();
1989
1990 test_take_primitive_arrays::<Int16Type>(
1992 vec![Some(0), None, Some(2), Some(3), None],
1993 &index,
1994 None,
1995 vec![Some(3), None, None, Some(3), Some(2)],
1996 )
1997 .unwrap();
1998
1999 test_take_primitive_arrays::<Int32Type>(
2001 vec![Some(0), None, Some(2), Some(3), None],
2002 &index,
2003 None,
2004 vec![Some(3), None, None, Some(3), Some(2)],
2005 )
2006 .unwrap();
2007
2008 test_take_primitive_arrays::<Int64Type>(
2010 vec![Some(0), None, Some(2), Some(3), None],
2011 &index,
2012 None,
2013 vec![Some(3), None, None, Some(3), Some(2)],
2014 )
2015 .unwrap();
2016
2017 test_take_primitive_arrays::<UInt8Type>(
2019 vec![Some(0), None, Some(2), Some(3), None],
2020 &index,
2021 None,
2022 vec![Some(3), None, None, Some(3), Some(2)],
2023 )
2024 .unwrap();
2025
2026 test_take_primitive_arrays::<UInt16Type>(
2028 vec![Some(0), None, Some(2), Some(3), None],
2029 &index,
2030 None,
2031 vec![Some(3), None, None, Some(3), Some(2)],
2032 )
2033 .unwrap();
2034
2035 test_take_primitive_arrays::<UInt32Type>(
2037 vec![Some(0), None, Some(2), Some(3), None],
2038 &index,
2039 None,
2040 vec![Some(3), None, None, Some(3), Some(2)],
2041 )
2042 .unwrap();
2043
2044 test_take_primitive_arrays::<Int64Type>(
2046 vec![Some(0), None, Some(2), Some(-15), None],
2047 &index,
2048 None,
2049 vec![Some(-15), None, None, Some(-15), Some(2)],
2050 )
2051 .unwrap();
2052
2053 test_take_primitive_arrays::<IntervalYearMonthType>(
2055 vec![Some(0), None, Some(2), Some(-15), None],
2056 &index,
2057 None,
2058 vec![Some(-15), None, None, Some(-15), Some(2)],
2059 )
2060 .unwrap();
2061
2062 let v1 = IntervalDayTime::new(0, 0);
2064 let v2 = IntervalDayTime::new(2, 0);
2065 let v3 = IntervalDayTime::new(-15, 0);
2066 test_take_primitive_arrays::<IntervalDayTimeType>(
2067 vec![Some(v1), None, Some(v2), Some(v3), None],
2068 &index,
2069 None,
2070 vec![Some(v3), None, None, Some(v3), Some(v2)],
2071 )
2072 .unwrap();
2073
2074 let v1 = IntervalMonthDayNano::new(0, 0, 0);
2076 let v2 = IntervalMonthDayNano::new(2, 0, 0);
2077 let v3 = IntervalMonthDayNano::new(-15, 0, 0);
2078 test_take_primitive_arrays::<IntervalMonthDayNanoType>(
2079 vec![Some(v1), None, Some(v2), Some(v3), None],
2080 &index,
2081 None,
2082 vec![Some(v3), None, None, Some(v3), Some(v2)],
2083 )
2084 .unwrap();
2085
2086 test_take_primitive_arrays::<DurationSecondType>(
2088 vec![Some(0), None, Some(2), Some(-15), None],
2089 &index,
2090 None,
2091 vec![Some(-15), None, None, Some(-15), Some(2)],
2092 )
2093 .unwrap();
2094
2095 test_take_primitive_arrays::<DurationMillisecondType>(
2097 vec![Some(0), None, Some(2), Some(-15), None],
2098 &index,
2099 None,
2100 vec![Some(-15), None, None, Some(-15), Some(2)],
2101 )
2102 .unwrap();
2103
2104 test_take_primitive_arrays::<DurationMicrosecondType>(
2106 vec![Some(0), None, Some(2), Some(-15), None],
2107 &index,
2108 None,
2109 vec![Some(-15), None, None, Some(-15), Some(2)],
2110 )
2111 .unwrap();
2112
2113 test_take_primitive_arrays::<DurationNanosecondType>(
2115 vec![Some(0), None, Some(2), Some(-15), None],
2116 &index,
2117 None,
2118 vec![Some(-15), None, None, Some(-15), Some(2)],
2119 )
2120 .unwrap();
2121
2122 test_take_primitive_arrays::<Float32Type>(
2124 vec![Some(0.0), None, Some(2.21), Some(-3.1), None],
2125 &index,
2126 None,
2127 vec![Some(-3.1), None, None, Some(-3.1), Some(2.21)],
2128 )
2129 .unwrap();
2130
2131 test_take_primitive_arrays::<Float64Type>(
2133 vec![Some(0.0), None, Some(2.21), Some(-3.1), None],
2134 &index,
2135 None,
2136 vec![Some(-3.1), None, None, Some(-3.1), Some(2.21)],
2137 )
2138 .unwrap();
2139 }
2140
2141 #[test]
2142 fn test_take_preserve_timezone() {
2143 let index = Int64Array::from(vec![Some(0), None]);
2144
2145 let input = TimestampNanosecondArray::from(vec![
2146 1_639_715_368_000_000_000,
2147 1_639_715_368_000_000_000,
2148 ])
2149 .with_timezone("UTC".to_string());
2150 let result = take(&input, &index, None).unwrap();
2151 match result.data_type() {
2152 DataType::Timestamp(TimeUnit::Nanosecond, tz) => {
2153 assert_eq!(tz.clone(), Some("UTC".into()))
2154 }
2155 _ => panic!(),
2156 }
2157 }
2158
2159 #[test]
2160 fn test_take_impl_primitive_with_int64_indices() {
2161 let index = Int64Array::from(vec![Some(3), None, Some(1), Some(3), Some(2)]);
2162
2163 test_take_impl_primitive_arrays::<Int16Type, Int64Type>(
2165 vec![Some(0), None, Some(2), Some(3), None],
2166 &index,
2167 None,
2168 vec![Some(3), None, None, Some(3), Some(2)],
2169 );
2170
2171 test_take_impl_primitive_arrays::<Int64Type, Int64Type>(
2173 vec![Some(0), None, Some(2), Some(-15), None],
2174 &index,
2175 None,
2176 vec![Some(-15), None, None, Some(-15), Some(2)],
2177 );
2178
2179 test_take_impl_primitive_arrays::<UInt64Type, Int64Type>(
2181 vec![Some(0), None, Some(2), Some(3), None],
2182 &index,
2183 None,
2184 vec![Some(3), None, None, Some(3), Some(2)],
2185 );
2186
2187 test_take_impl_primitive_arrays::<DurationMillisecondType, Int64Type>(
2189 vec![Some(0), None, Some(2), Some(-15), None],
2190 &index,
2191 None,
2192 vec![Some(-15), None, None, Some(-15), Some(2)],
2193 );
2194
2195 test_take_impl_primitive_arrays::<Float32Type, Int64Type>(
2197 vec![Some(0.0), None, Some(2.21), Some(-3.1), None],
2198 &index,
2199 None,
2200 vec![Some(-3.1), None, None, Some(-3.1), Some(2.21)],
2201 );
2202 }
2203
2204 #[test]
2205 fn test_take_impl_primitive_with_uint8_indices() {
2206 let index = UInt8Array::from(vec![Some(3), None, Some(1), Some(3), Some(2)]);
2207
2208 test_take_impl_primitive_arrays::<Int16Type, UInt8Type>(
2210 vec![Some(0), None, Some(2), Some(3), None],
2211 &index,
2212 None,
2213 vec![Some(3), None, None, Some(3), Some(2)],
2214 );
2215
2216 test_take_impl_primitive_arrays::<DurationMillisecondType, UInt8Type>(
2218 vec![Some(0), None, Some(2), Some(-15), None],
2219 &index,
2220 None,
2221 vec![Some(-15), None, None, Some(-15), Some(2)],
2222 );
2223
2224 test_take_impl_primitive_arrays::<Float32Type, UInt8Type>(
2226 vec![Some(0.0), None, Some(2.21), Some(-3.1), None],
2227 &index,
2228 None,
2229 vec![Some(-3.1), None, None, Some(-3.1), Some(2.21)],
2230 );
2231 }
2232
2233 #[test]
2234 fn test_take_bool() {
2235 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(3), Some(2)]);
2236 test_take_boolean_arrays(
2238 vec![Some(false), None, Some(true), Some(false), None],
2239 &index,
2240 None,
2241 vec![Some(false), None, None, Some(false), Some(true)],
2242 );
2243 }
2244
2245 #[test]
2246 fn test_take_bool_nullable_index() {
2247 let index = UInt32Array::new(
2249 ScalarBuffer::from(vec![99, 0, 999, 1, 9999, 2]),
2250 Some(NullBuffer::from(vec![
2251 false, true, false, true, false, true,
2252 ])),
2253 );
2254 test_take_boolean_arrays(
2255 vec![Some(true), None, Some(false)],
2256 &index,
2257 None,
2258 vec![None, Some(true), None, None, None, Some(false)],
2259 );
2260 }
2261
2262 #[test]
2263 fn test_take_bool_nullable_index_nonnull_values() {
2264 let index = UInt32Array::new(
2266 ScalarBuffer::from(vec![99, 0, 999, 1, 9999, 2]),
2267 Some(NullBuffer::from(vec![
2268 false, true, false, true, false, true,
2269 ])),
2270 );
2271 test_take_boolean_arrays(
2272 vec![Some(true), Some(true), Some(false)],
2273 &index,
2274 None,
2275 vec![None, Some(true), None, Some(true), None, Some(false)],
2276 );
2277 }
2278
2279 #[test]
2280 fn test_take_bool_with_offset() {
2281 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(3), Some(2), None]);
2282 let index = index.slice(2, 4);
2283 let index = index
2284 .as_any()
2285 .downcast_ref::<PrimitiveArray<UInt32Type>>()
2286 .unwrap();
2287
2288 test_take_boolean_arrays(
2290 vec![Some(false), None, Some(true), Some(false), None],
2291 index,
2292 None,
2293 vec![None, Some(false), Some(true), None],
2294 );
2295 }
2296
2297 #[test]
2298 fn test_take_bool_nullable_index_sliced_source() {
2300 let source = BooleanArray::from(vec![Some(true), Some(false), Some(true), Some(false)]);
2301 let source = source.slice(1, 3); let source = source;
2303
2304 let indices = UInt32Array::from(vec![Some(2), None, Some(0)]);
2305 let result = take(&source, &indices, None).unwrap();
2306 let result = result.as_any().downcast_ref::<BooleanArray>().unwrap();
2307
2308 let expected = BooleanArray::from(vec![Some(false), None, Some(false)]);
2309 assert_eq!(result, &expected);
2310 }
2311
2312 #[test]
2313 fn test_take_bool_no_nulls_multi_byte() {
2315 let source = BooleanArray::from(vec![
2316 true, false, true, true, false, false, true, false, true, true,
2317 ]);
2318 let indices = UInt32Array::from(vec![0, 2, 4, 6, 8, 1, 3, 5, 7, 9]);
2319 let result = take(&source, &indices, None).unwrap();
2320 let result = result.as_any().downcast_ref::<BooleanArray>().unwrap();
2321 let expected = BooleanArray::from(vec![
2322 true, true, false, true, true, false, true, false, false, true,
2323 ]);
2324 assert_eq!(result, &expected);
2325 }
2326
2327 #[test]
2328 fn test_take_bool_no_nulls_sliced_source() {
2330 let source = BooleanArray::from(vec![true, false, true, false, true]);
2331 let source = source.slice(2, 3); let source = source.as_any().downcast_ref::<BooleanArray>().unwrap();
2333 let indices = UInt32Array::from(vec![2, 0, 1]);
2334 let result = take(source, &indices, None).unwrap();
2335 let result = result.as_any().downcast_ref::<BooleanArray>().unwrap();
2336 let expected = BooleanArray::from(vec![true, true, false]);
2337 assert_eq!(result, &expected);
2338 }
2339
2340 #[test]
2341 fn test_take_bool_nullable_values_multi_byte() {
2343 let source = BooleanArray::from(vec![
2344 Some(true),
2345 None,
2346 Some(false),
2347 Some(true),
2348 None,
2349 Some(false),
2350 Some(true),
2351 Some(false),
2352 Some(true),
2353 None,
2354 ]);
2355 let indices = UInt32Array::from(vec![0, 2, 4, 6, 8, 1, 3, 5, 7, 9]);
2356 let result = take(&source, &indices, None).unwrap();
2357 let result = result.as_any().downcast_ref::<BooleanArray>().unwrap();
2358 let expected = BooleanArray::from(vec![
2359 Some(true),
2360 Some(false),
2361 None,
2362 Some(true),
2363 Some(true),
2364 None,
2365 Some(true),
2366 Some(false),
2367 Some(false),
2368 None,
2369 ]);
2370 assert_eq!(result, &expected);
2371 }
2372
2373 #[test]
2374 fn test_take_bool_nullable_values_sliced_source_null_indices() {
2376 let source =
2377 BooleanArray::from(vec![Some(true), Some(false), None, Some(true), Some(false)]);
2378 let source = source.slice(1, 4); let source = source.as_any().downcast_ref::<BooleanArray>().unwrap();
2380 let indices = UInt32Array::from(vec![Some(3), None, Some(1), Some(0)]);
2381 let result = take(source, &indices, None).unwrap();
2382 let result = result.as_any().downcast_ref::<BooleanArray>().unwrap();
2383 let expected = BooleanArray::from(vec![Some(false), None, None, Some(false)]);
2384 assert_eq!(result, &expected);
2385 }
2386
2387 #[test]
2388 #[should_panic(expected = "assertion failed: idx < self.bit_len")]
2389 fn test_take_bool_oob_no_check_bounds_panics() {
2390 let array = BooleanArray::from(vec![true, false, true]);
2391 let indices = Int32Array::from(vec![0, 1, 10]);
2392 take(&array, &indices, None).unwrap();
2393 }
2394
2395 fn _test_take_string<'a, K>()
2396 where
2397 K: Array + PartialEq + From<Vec<Option<&'a str>>> + 'static,
2398 {
2399 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(3), Some(4)]);
2400
2401 let array = K::from(vec![
2402 Some("one"),
2403 None,
2404 Some("three"),
2405 Some("four"),
2406 Some("five"),
2407 ]);
2408 let actual = take(&array, &index, None).unwrap();
2409 assert_eq!(actual.len(), index.len());
2410
2411 let actual = actual.as_any().downcast_ref::<K>().unwrap();
2412
2413 let expected = K::from(vec![Some("four"), None, None, Some("four"), Some("five")]);
2414
2415 assert_eq!(actual, &expected);
2416 }
2417
2418 #[test]
2419 fn test_take_string() {
2420 _test_take_string::<StringArray>()
2421 }
2422
2423 #[test]
2424 fn test_take_large_string() {
2425 _test_take_string::<LargeStringArray>()
2426 }
2427
2428 #[test]
2429 fn test_take_slice_string() {
2430 let strings = StringArray::from(vec![Some("hello"), None, Some("world"), None, Some("hi")]);
2431 let indices = Int32Array::from(vec![Some(0), Some(1), None, Some(0), Some(2)]);
2432 let indices_slice = indices.slice(1, 4);
2433 let expected = StringArray::from(vec![None, None, Some("hello"), Some("world")]);
2434 let result = take(&strings, &indices_slice, None).unwrap();
2435 assert_eq!(result.as_ref(), &expected);
2436 }
2437
2438 #[test]
2443 fn test_take_bytes_sliced_values() {
2444 let values = StringArray::from(vec![
2445 Some("aaa"),
2446 Some("bbb"),
2447 None,
2448 Some("ccccc"),
2449 Some("dd"),
2450 None,
2451 Some("eeee"),
2452 ]);
2453 let sliced = values.slice(2, 5);
2456
2457 let indices = Int32Array::from(vec![1, 2, 4, 1]);
2460 let result = take(&sliced, &indices, None).unwrap();
2461 let expected =
2462 StringArray::from(vec![Some("ccccc"), Some("dd"), Some("eeee"), Some("ccccc")]);
2463 assert_eq!(result.as_string::<i32>(), &expected);
2464
2465 let indices = Int32Array::from(vec![Some(1), None, Some(0), Some(4), Some(3)]);
2468 let result = take(&sliced, &indices, None).unwrap();
2469 let expected = StringArray::from(vec![Some("ccccc"), None, None, Some("eeee"), None]);
2470 assert_eq!(result.as_string::<i32>(), &expected);
2471 }
2472
2473 fn _test_byte_view<T>()
2474 where
2475 T: ByteViewType,
2476 str: AsRef<T::Native>,
2477 T::Native: PartialEq,
2478 {
2479 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(3), Some(4), Some(2)]);
2480 let array = {
2481 let mut builder = GenericByteViewBuilder::<T>::new();
2483 builder.append_value("hello");
2484 builder.append_value("world");
2485 builder.append_null();
2486 builder.append_value("large payload over 12 bytes");
2487 builder.append_value("lulu");
2488 builder.finish()
2489 };
2490
2491 let actual = take(&array, &index, None).unwrap();
2492
2493 assert_eq!(actual.len(), index.len());
2494 let actual_buffers = actual.as_byte_view::<T>().data_buffers();
2495 let input_buffers = array.data_buffers();
2496 assert!(Arc::ptr_eq(actual_buffers, input_buffers));
2497
2498 let expected = {
2499 let mut builder = GenericByteViewBuilder::<T>::new();
2501 builder.append_value("large payload over 12 bytes");
2502 builder.append_null();
2503 builder.append_value("world");
2504 builder.append_value("large payload over 12 bytes");
2505 builder.append_value("lulu");
2506 builder.append_null();
2507 builder.finish()
2508 };
2509
2510 assert_eq!(actual.as_ref(), &expected);
2511 }
2512
2513 #[test]
2514 fn test_take_string_view() {
2515 _test_byte_view::<StringViewType>()
2516 }
2517
2518 #[test]
2519 fn test_take_binary_view() {
2520 _test_byte_view::<BinaryViewType>()
2521 }
2522
2523 macro_rules! test_take_list {
2524 ($offset_type:ty, $list_data_type:ident, $list_array_type:ident) => {{
2525 let values = Arc::new(Int32Array::from(vec![0, 0, 0, -1, -2, -1, 2, 3]));
2527 let value_offsets =
2528 OffsetBuffer::<$offset_type>::new(ScalarBuffer::from(vec![0, 3, 6, 6, 8]));
2529 let field = Arc::new(Field::new_list_field(DataType::Int32, false));
2530 let list_array = $list_array_type::new(Arc::clone(&field), value_offsets, values, None);
2531
2532 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(2), Some(0)]);
2534
2535 let a = take(&list_array, &index, None).unwrap();
2536 let a: &$list_array_type = a.as_any().downcast_ref::<$list_array_type>().unwrap();
2537
2538 let expected_values = Arc::new(Int32Array::from(vec![
2541 Some(2),
2542 Some(3),
2543 Some(-1),
2544 Some(-2),
2545 Some(-1),
2546 Some(0),
2547 Some(0),
2548 Some(0),
2549 ]));
2550 let expected_offsets =
2551 OffsetBuffer::<$offset_type>::new(ScalarBuffer::from(vec![0, 2, 2, 5, 5, 8]));
2552 let expected_list_array = $list_array_type::new(
2553 field,
2554 expected_offsets,
2555 expected_values,
2556 index.nulls().cloned(),
2558 );
2559
2560 assert_eq!(a, &expected_list_array);
2561 }};
2562 }
2563
2564 macro_rules! test_take_list_with_value_nulls {
2565 ($offset_type:ty, $list_data_type:ident, $list_array_type:ident) => {{
2566 let values = Arc::new(Int32Array::from(vec![
2568 Some(0),
2569 None,
2570 Some(0),
2571 Some(-1),
2572 Some(-2),
2573 Some(3),
2574 None,
2575 Some(5),
2576 None,
2577 ]));
2578 let value_offsets =
2579 OffsetBuffer::<$offset_type>::new(ScalarBuffer::from(vec![0, 3, 6, 7, 9]));
2580 let field = Arc::new(Field::new_list_field(DataType::Int32, true));
2581 let list_array = $list_array_type::new(Arc::clone(&field), value_offsets, values, None);
2582
2583 let index = UInt32Array::from(vec![Some(2), None, Some(1), Some(3), Some(0)]);
2585
2586 let a = take(&list_array, &index, None).unwrap();
2587 let a: &$list_array_type = a.as_any().downcast_ref::<$list_array_type>().unwrap();
2588
2589 let expected_values = Arc::new(Int32Array::from(vec![
2592 None,
2593 Some(-1),
2594 Some(-2),
2595 Some(3),
2596 Some(5),
2597 None,
2598 Some(0),
2599 None,
2600 Some(0),
2601 ]));
2602 let expected_offsets =
2603 OffsetBuffer::<$offset_type>::new(ScalarBuffer::from(vec![0, 1, 1, 4, 6, 9]));
2604 let expected_list_array = $list_array_type::new(
2605 field,
2606 expected_offsets,
2607 expected_values,
2608 index.nulls().cloned(),
2610 );
2611
2612 assert_eq!(a, &expected_list_array);
2613 }};
2614 }
2615
2616 macro_rules! test_take_list_with_nulls {
2617 ($offset_type:ty, $list_data_type:ident, $list_array_type:ident) => {{
2618 let values = Arc::new(Int32Array::from(vec![
2620 Some(0),
2621 None,
2622 Some(0),
2623 Some(-1),
2624 Some(-2),
2625 Some(3),
2626 Some(5),
2627 None,
2628 ]));
2629 let value_offsets =
2630 OffsetBuffer::<$offset_type>::new(ScalarBuffer::from(vec![0, 3, 6, 6, 8]));
2631 let field = Arc::new(Field::new_list_field(DataType::Int32, true));
2632 let list_nulls = NullBuffer::from(vec![true, true, false, true]);
2634 let list_array =
2635 $list_array_type::new(Arc::clone(&field), value_offsets, values, Some(list_nulls));
2636
2637 let index = UInt32Array::from(vec![Some(2), None, Some(1), Some(3), Some(0)]);
2639
2640 let a = take(&list_array, &index, None).unwrap();
2641 let a: &$list_array_type = a.as_any().downcast_ref::<$list_array_type>().unwrap();
2642
2643 let expected_values = Arc::new(Int32Array::from(vec![
2646 Some(-1),
2647 Some(-2),
2648 Some(3),
2649 Some(5),
2650 None,
2651 Some(0),
2652 None,
2653 Some(0),
2654 ]));
2655 let expected_offsets =
2656 OffsetBuffer::<$offset_type>::new(ScalarBuffer::from(vec![0, 0, 0, 3, 5, 8]));
2657 let expected_nulls = NullBuffer::from(vec![false, false, true, true, true]);
2659 let expected_list_array = $list_array_type::new(
2660 field,
2661 expected_offsets,
2662 expected_values,
2663 Some(expected_nulls),
2664 );
2665
2666 assert_eq!(a, &expected_list_array);
2667 }};
2668 }
2669
2670 fn test_take_list_view_generic<OffsetType: OffsetSizeTrait, ValuesType: ArrowPrimitiveType, F>(
2671 values: Vec<Option<Vec<Option<ValuesType::Native>>>>,
2672 take_indices: Vec<Option<usize>>,
2673 expected: Vec<Option<Vec<Option<ValuesType::Native>>>>,
2674 mapper: F,
2675 ) where
2676 F: Fn(GenericListViewArray<OffsetType>) -> GenericListViewArray<OffsetType>,
2677 {
2678 let mut list_view_array =
2679 GenericListViewBuilder::<OffsetType, _>::new(PrimitiveBuilder::<ValuesType>::new());
2680
2681 for value in values {
2682 list_view_array.append_option(value);
2683 }
2684 let list_view_array = list_view_array.finish();
2685 let list_view_array = mapper(list_view_array);
2686
2687 let mut indices = UInt64Builder::new();
2688 for idx in take_indices {
2689 indices.append_option(idx.map(|i| i.to_u64().unwrap()));
2690 }
2691 let indices = indices.finish();
2692
2693 let taken = take(&list_view_array, &indices, None)
2694 .unwrap()
2695 .as_list_view()
2696 .clone();
2697
2698 let mut expected_array =
2699 GenericListViewBuilder::<OffsetType, _>::new(PrimitiveBuilder::<ValuesType>::new());
2700 for value in expected {
2701 expected_array.append_option(value);
2702 }
2703 let expected_array = expected_array.finish();
2704
2705 assert_eq!(taken, expected_array);
2706 }
2707
2708 macro_rules! list_view_test_case {
2709 (values: $values:expr, indices: $indices:expr, expected: $expected: expr) => {{
2710 test_take_list_view_generic::<i32, Int8Type, _>($values, $indices, $expected, |x| x);
2711 test_take_list_view_generic::<i64, Int8Type, _>($values, $indices, $expected, |x| x);
2712 }};
2713 (values: $values:expr, transform: $fn:expr, indices: $indices:expr, expected: $expected: expr) => {{
2714 test_take_list_view_generic::<i32, Int8Type, _>($values, $indices, $expected, $fn);
2715 test_take_list_view_generic::<i64, Int8Type, _>($values, $indices, $expected, $fn);
2716 }};
2717 }
2718
2719 fn do_take_fixed_size_list_test<T>(
2720 length: <Int32Type as ArrowPrimitiveType>::Native,
2721 input_data: Vec<Option<Vec<Option<T::Native>>>>,
2722 indices: Vec<<UInt32Type as ArrowPrimitiveType>::Native>,
2723 expected_data: Vec<Option<Vec<Option<T::Native>>>>,
2724 ) where
2725 T: ArrowPrimitiveType,
2726 PrimitiveArray<T>: From<Vec<Option<T::Native>>>,
2727 {
2728 let indices = UInt32Array::from(indices);
2729
2730 let input_array = FixedSizeListArray::from_iter_primitive::<T, _, _>(input_data, length);
2731
2732 let output =
2733 take_fixed_size_list::<_, true>(&input_array, &indices, length as u32).unwrap();
2734
2735 let expected = FixedSizeListArray::from_iter_primitive::<T, _, _>(expected_data, length);
2736
2737 assert_eq!(&output, &expected)
2738 }
2739
2740 #[test]
2741 fn test_take_list_primitive_child_null_indices() {
2743 let list = ListArray::from_iter_primitive::<Int32Type, _, _>(vec![
2746 Some(vec![Some(1)]),
2747 Some(vec![Some(2), Some(3), Some(4)]),
2748 Some(vec![Some(5), Some(6)]),
2749 ]);
2750 let indices = Int32Array::from(vec![Some(2), None, Some(0), Some(1)]);
2751 let result = take(&list, &indices, None).unwrap();
2752 let result = result.as_any().downcast_ref::<ListArray>().unwrap();
2753
2754 let expected = ListArray::from_iter_primitive::<Int32Type, _, _>(vec![
2755 Some(vec![Some(5), Some(6)]),
2756 None,
2757 Some(vec![Some(1)]),
2758 Some(vec![Some(2), Some(3), Some(4)]),
2759 ]);
2760 assert_eq!(result, &expected);
2761 }
2762
2763 #[test]
2764 fn test_take_list() {
2765 test_take_list!(i32, List, ListArray);
2766 }
2767
2768 #[test]
2769 fn test_take_large_list() {
2770 test_take_list!(i64, LargeList, LargeListArray);
2771 }
2772
2773 #[test]
2774 fn test_take_list_with_value_nulls() {
2775 test_take_list_with_value_nulls!(i32, List, ListArray);
2776 }
2777
2778 #[test]
2779 fn test_take_large_list_with_value_nulls() {
2780 test_take_list_with_value_nulls!(i64, LargeList, LargeListArray);
2781 }
2782
2783 #[test]
2784 fn test_test_take_list_with_nulls() {
2785 test_take_list_with_nulls!(i32, List, ListArray);
2786 }
2787
2788 #[test]
2789 fn test_test_take_large_list_with_nulls() {
2790 test_take_list_with_nulls!(i64, LargeList, LargeListArray);
2791 }
2792
2793 #[test]
2794 fn test_test_take_list_view_reversed() {
2795 list_view_test_case! {
2797 values: vec![
2798 Some(vec![Some(1), None, Some(3)]),
2799 None,
2800 Some(vec![Some(7), Some(8), None]),
2801 ],
2802 indices: vec![Some(2), Some(1), Some(0)],
2803 expected: vec![
2804 Some(vec![Some(7), Some(8), None]),
2805 None,
2806 Some(vec![Some(1), None, Some(3)]),
2807 ]
2808 }
2809 }
2810
2811 #[test]
2812 fn test_take_list_view_null_indices() {
2813 list_view_test_case! {
2815 values: vec![
2816 Some(vec![Some(1), None, Some(3)]),
2817 None,
2818 Some(vec![Some(7), Some(8), None]),
2819 ],
2820 indices: vec![None, Some(0), None],
2821 expected: vec![None, Some(vec![Some(1), None, Some(3)]), None]
2822 }
2823 }
2824
2825 #[test]
2826 fn test_take_list_view_null_values() {
2827 list_view_test_case! {
2829 values: vec![
2830 Some(vec![Some(1), None, Some(3)]),
2831 None,
2832 Some(vec![Some(7), Some(8), None]),
2833 ],
2834 indices: vec![Some(1), Some(1), Some(1), None, None],
2835 expected: vec![None; 5]
2836 }
2837 }
2838
2839 #[test]
2840 fn test_take_list_view_sliced() {
2841 list_view_test_case! {
2843 values: vec![
2844 Some(vec![Some(1)]),
2845 None,
2846 None,
2847 Some(vec![Some(2), Some(3)]),
2848 Some(vec![Some(4), Some(5)]),
2849 None,
2850 ],
2851 transform: |l| l.slice(2, 4),
2852 indices: vec![Some(0), Some(3), None, Some(1), Some(2)],
2853 expected: vec![
2854 None, None, None, Some(vec![Some(2), Some(3)]), Some(vec![Some(4), Some(5)])
2855 ]
2856 }
2857 }
2858
2859 #[test]
2860 fn test_take_fixed_size_list() {
2861 do_take_fixed_size_list_test::<Int32Type>(
2862 3,
2863 vec![
2864 Some(vec![None, Some(1), Some(2)]),
2865 Some(vec![Some(3), Some(4), None]),
2866 Some(vec![Some(6), Some(7), Some(8)]),
2867 ],
2868 vec![2, 1, 0],
2869 vec![
2870 Some(vec![Some(6), Some(7), Some(8)]),
2871 Some(vec![Some(3), Some(4), None]),
2872 Some(vec![None, Some(1), Some(2)]),
2873 ],
2874 );
2875
2876 do_take_fixed_size_list_test::<UInt8Type>(
2877 1,
2878 vec![
2879 Some(vec![Some(1)]),
2880 Some(vec![Some(2)]),
2881 Some(vec![Some(3)]),
2882 Some(vec![Some(4)]),
2883 Some(vec![Some(5)]),
2884 Some(vec![Some(6)]),
2885 Some(vec![Some(7)]),
2886 Some(vec![Some(8)]),
2887 ],
2888 vec![2, 7, 0],
2889 vec![
2890 Some(vec![Some(3)]),
2891 Some(vec![Some(8)]),
2892 Some(vec![Some(1)]),
2893 ],
2894 );
2895
2896 do_take_fixed_size_list_test::<UInt64Type>(
2897 3,
2898 vec![
2899 Some(vec![Some(10), Some(11), Some(12)]),
2900 Some(vec![Some(13), Some(14), Some(15)]),
2901 None,
2902 Some(vec![Some(16), Some(17), Some(18)]),
2903 ],
2904 vec![3, 2, 1, 2, 0],
2905 vec![
2906 Some(vec![Some(16), Some(17), Some(18)]),
2907 None,
2908 Some(vec![Some(13), Some(14), Some(15)]),
2909 None,
2910 Some(vec![Some(10), Some(11), Some(12)]),
2911 ],
2912 );
2913 }
2914
2915 #[test]
2916 fn test_take_fixed_size_binary_with_nulls_indices() {
2917 let fsb = FixedSizeBinaryArray::try_from_sparse_iter_with_size(
2918 [
2919 Some(vec![0x01, 0x01, 0x01, 0x01]),
2920 Some(vec![0x02, 0x02, 0x02, 0x02]),
2921 Some(vec![0x03, 0x03, 0x03, 0x03]),
2922 Some(vec![0x04, 0x04, 0x04, 0x04]),
2923 ]
2924 .into_iter(),
2925 4,
2926 )
2927 .unwrap();
2928
2929 let indices = UInt32Array::from(vec![Some(0), None, None, Some(3)]);
2931
2932 let result = take_fixed_size_binary::<_, true>(&fsb, &indices, 4).unwrap();
2933 assert_eq!(result.len(), 4);
2934 assert_eq!(result.null_count(), 2);
2935 assert_eq!(
2936 result.nulls().unwrap().iter().collect::<Vec<_>>(),
2937 vec![true, false, false, true]
2938 );
2939 }
2940
2941 #[test]
2945 fn test_take_fixed_size_binary_with_nulls_indices_not_optimized_length() {
2946 let fsb = FixedSizeBinaryArray::try_from_sparse_iter_with_size(
2947 [
2948 Some(vec![0x01, 0x01, 0x01, 0x01, 0x01]),
2949 Some(vec![0x02, 0x02, 0x02, 0x02, 0x01]),
2950 Some(vec![0x03, 0x03, 0x03, 0x03, 0x01]),
2951 Some(vec![0x04, 0x04, 0x04, 0x04, 0x01]),
2952 ]
2953 .into_iter(),
2954 5,
2955 )
2956 .unwrap();
2957
2958 let indices = UInt32Array::from(vec![Some(0), None, None, Some(3)]);
2960
2961 let result = take_fixed_size_binary::<_, true>(&fsb, &indices, 5).unwrap();
2962 assert_eq!(result.len(), 4);
2963 assert_eq!(result.null_count(), 2);
2964 assert_eq!(
2965 result.nulls().unwrap().iter().collect::<Vec<_>>(),
2966 vec![true, false, false, true]
2967 );
2968 }
2969
2970 #[test]
2971 #[should_panic(expected = "index out of bounds: the len is 4 but the index is 1000")]
2972 fn test_take_list_out_of_bounds() {
2973 let values = Arc::new(Int32Array::from(vec![0, 0, 0, -1, -2, -1, 2, 3]));
2975 let value_offsets = OffsetBuffer::<i32>::new(ScalarBuffer::from(vec![0, 3, 6, 8]));
2977 let field = Arc::new(Field::new_list_field(DataType::Int32, false));
2979 let list_array = ListArray::new(field, value_offsets, values, None);
2980
2981 let index = UInt32Array::from(vec![1000]);
2982
2983 take(&list_array, &index, None).unwrap();
2986 }
2987
2988 #[test]
2989 fn test_take_map() {
2990 let values = Int32Array::from(vec![1, 2, 3, 4]);
2991 let array =
2992 MapArray::new_from_strings(vec!["a", "b", "c", "a"].into_iter(), &values, &[0, 3, 4])
2993 .unwrap();
2994
2995 let index = UInt32Array::from(vec![0]);
2996
2997 let result = take(&array, &index, None).unwrap();
2998 let expected: ArrayRef = Arc::new(
2999 MapArray::new_from_strings(
3000 vec!["a", "b", "c"].into_iter(),
3001 &values.slice(0, 3),
3002 &[0, 3],
3003 )
3004 .unwrap(),
3005 );
3006 assert_eq!(&expected, &result);
3007 }
3008
3009 #[test]
3010 fn test_take_struct() {
3011 let array = create_test_struct(vec![
3012 Some((Some(true), Some(42))),
3013 Some((Some(false), Some(28))),
3014 Some((Some(false), Some(19))),
3015 Some((Some(true), Some(31))),
3016 None,
3017 ]);
3018
3019 let index = UInt32Array::from(vec![0, 3, 1, 0, 2, 4]);
3020 let actual = take(&array, &index, None).unwrap();
3021 let actual: &StructArray = actual.as_any().downcast_ref::<StructArray>().unwrap();
3022 assert_eq!(index.len(), actual.len());
3023 assert_eq!(1, actual.null_count());
3024
3025 let expected = create_test_struct(vec![
3026 Some((Some(true), Some(42))),
3027 Some((Some(true), Some(31))),
3028 Some((Some(false), Some(28))),
3029 Some((Some(true), Some(42))),
3030 Some((Some(false), Some(19))),
3031 None,
3032 ]);
3033
3034 assert_eq!(&expected, actual);
3035
3036 let nulls = NullBuffer::from(&[false, true, false, true, false, true]);
3037 let empty_struct_arr = StructArray::new_empty_fields(6, Some(nulls));
3038 let index = UInt32Array::from(vec![0, 2, 1, 4]);
3039 let actual = take(&empty_struct_arr, &index, None).unwrap();
3040
3041 let expected_nulls = NullBuffer::from(&[false, false, true, false]);
3042 let expected_struct_arr = StructArray::new_empty_fields(4, Some(expected_nulls));
3043 assert_eq!(&expected_struct_arr, actual.as_struct());
3044 }
3045
3046 #[test]
3047 fn test_take_struct_with_null_indices() {
3048 let array = create_test_struct(vec![
3049 Some((Some(true), Some(42))),
3050 Some((Some(false), Some(28))),
3051 Some((Some(false), Some(19))),
3052 Some((Some(true), Some(31))),
3053 None,
3054 ]);
3055
3056 let index = UInt32Array::from(vec![None, Some(3), Some(1), None, Some(0), Some(4)]);
3057 let actual = take(&array, &index, None).unwrap();
3058 let actual: &StructArray = actual.as_any().downcast_ref::<StructArray>().unwrap();
3059 assert_eq!(index.len(), actual.len());
3060 assert_eq!(3, actual.null_count()); let expected = create_test_struct(vec![
3063 None,
3064 Some((Some(true), Some(31))),
3065 Some((Some(false), Some(28))),
3066 None,
3067 Some((Some(true), Some(42))),
3068 None,
3069 ]);
3070
3071 assert_eq!(&expected, actual);
3072 }
3073
3074 #[test]
3075 fn test_take_out_of_bounds() {
3076 let index = UInt32Array::from(vec![Some(3), None, Some(1), Some(3), Some(6)]);
3077 let take_opt = TakeOptions { check_bounds: true };
3078
3079 let result = test_take_primitive_arrays::<Int64Type>(
3081 vec![Some(0), None, Some(2), Some(3), None],
3082 &index,
3083 Some(take_opt),
3084 vec![None],
3085 );
3086 assert!(result.is_err());
3087 }
3088
3089 #[test]
3090 #[should_panic(expected = "index out of bounds: the len is 4 but the index is 1000")]
3091 fn test_take_out_of_bounds_panic() {
3092 let index = UInt32Array::from(vec![Some(1000)]);
3093
3094 test_take_primitive_arrays::<Int64Type>(
3095 vec![Some(0), Some(1), Some(2), Some(3)],
3096 &index,
3097 None,
3098 vec![None],
3099 )
3100 .unwrap();
3101 }
3102
3103 #[test]
3104 fn test_null_array_smaller_than_indices() {
3105 let values = NullArray::new(2);
3106 let indices = UInt32Array::from(vec![Some(0), None, Some(15)]);
3107
3108 let result = take(&values, &indices, None).unwrap();
3109 let expected: ArrayRef = Arc::new(NullArray::new(3));
3110 assert_eq!(&result, &expected);
3111 }
3112
3113 #[test]
3114 fn test_null_array_larger_than_indices() {
3115 let values = NullArray::new(5);
3116 let indices = UInt32Array::from(vec![Some(0), None, Some(15)]);
3117
3118 let result = take(&values, &indices, None).unwrap();
3119 let expected: ArrayRef = Arc::new(NullArray::new(3));
3120 assert_eq!(&result, &expected);
3121 }
3122
3123 #[test]
3124 fn test_null_array_indices_out_of_bounds() {
3125 let values = NullArray::new(5);
3126 let indices = UInt32Array::from(vec![Some(0), None, Some(15)]);
3127
3128 let result = take(&values, &indices, Some(TakeOptions { check_bounds: true }));
3129 assert_eq!(
3130 result.unwrap_err().to_string(),
3131 "Compute error: Array index out of bounds, cannot get item at index 15 from 5 entries"
3132 );
3133 }
3134
3135 #[test]
3136 fn test_take_dict() {
3137 let mut dict_builder = StringDictionaryBuilder::<Int16Type>::new();
3138
3139 dict_builder.append("foo").unwrap();
3140 dict_builder.append("bar").unwrap();
3141 dict_builder.append("").unwrap();
3142 dict_builder.append_null();
3143 dict_builder.append("foo").unwrap();
3144 dict_builder.append("bar").unwrap();
3145 dict_builder.append("bar").unwrap();
3146 dict_builder.append("foo").unwrap();
3147
3148 let array = dict_builder.finish();
3149 let dict_values = array.values().clone();
3150 let dict_values = dict_values.as_any().downcast_ref::<StringArray>().unwrap();
3151
3152 let indices = UInt32Array::from(vec![
3153 Some(0), Some(7), None, Some(5), Some(6), Some(2), Some(3), ]);
3161
3162 let result = take(&array, &indices, None).unwrap();
3163 let result = result
3164 .as_any()
3165 .downcast_ref::<DictionaryArray<Int16Type>>()
3166 .unwrap();
3167
3168 let result_values: StringArray = result.values().to_data().into();
3169
3170 let expected_values = StringArray::from(vec!["foo", "bar", ""]);
3172 assert_eq!(&expected_values, dict_values);
3173 assert_eq!(&expected_values, &result_values);
3174
3175 let expected_keys = Int16Array::from(vec![
3176 Some(0),
3177 Some(0),
3178 None,
3179 Some(1),
3180 Some(1),
3181 Some(2),
3182 None,
3183 ]);
3184 assert_eq!(result.keys(), &expected_keys);
3185 }
3186
3187 fn build_generic_list<S, T>(data: Vec<Option<Vec<T::Native>>>) -> GenericListArray<S>
3188 where
3189 S: OffsetSizeTrait + 'static,
3190 T: ArrowPrimitiveType,
3191 PrimitiveArray<T>: From<Vec<Option<T::Native>>>,
3192 {
3193 GenericListArray::from_iter_primitive::<T, _, _>(
3194 data.iter()
3195 .map(|x| x.as_ref().map(|x| x.iter().map(|x| Some(*x)))),
3196 )
3197 }
3198
3199 fn test_take_sliced_list_generic<S: OffsetSizeTrait + 'static>() {
3200 let list = build_generic_list::<S, Int32Type>(vec![
3201 Some(vec![0, 1]),
3202 Some(vec![2, 3, 4]),
3203 None,
3204 Some(vec![]),
3205 Some(vec![5, 6]),
3206 Some(vec![7]),
3207 ]);
3208 let sliced = list.slice(1, 4);
3209 let indices = UInt32Array::from(vec![Some(3), Some(0), None, Some(2), Some(1)]);
3210
3211 let taken = take(&sliced, &indices, None).unwrap();
3212 let taken = taken.as_list::<S>();
3213
3214 let expected = build_generic_list::<S, Int32Type>(vec![
3215 Some(vec![5, 6]),
3216 Some(vec![2, 3, 4]),
3217 None,
3218 Some(vec![]),
3219 None,
3220 ]);
3221
3222 assert_eq!(taken, &expected);
3223 }
3224
3225 fn test_take_sliced_list_with_value_nulls_generic<S: OffsetSizeTrait + 'static>() {
3226 let list = GenericListArray::<S>::from_iter_primitive::<Int32Type, _, _>(vec![
3227 Some(vec![Some(10)]),
3228 Some(vec![None, Some(1)]),
3229 None,
3230 Some(vec![Some(2), None]),
3231 Some(vec![]),
3232 Some(vec![Some(3)]),
3233 ]);
3234 let sliced = list.slice(1, 4);
3235 let indices = UInt32Array::from(vec![Some(2), Some(0), None, Some(3), Some(1)]);
3236
3237 let taken = take(&sliced, &indices, None).unwrap();
3238 let taken = taken.as_list::<S>();
3239
3240 let expected = GenericListArray::<S>::from_iter_primitive::<Int32Type, _, _>(vec![
3241 Some(vec![Some(2), None]),
3242 Some(vec![None, Some(1)]),
3243 None,
3244 Some(vec![]),
3245 None,
3246 ]);
3247
3248 assert_eq!(taken, &expected);
3249 }
3250
3251 #[test]
3252 fn test_take_sliced_list() {
3253 test_take_sliced_list_generic::<i32>();
3254 }
3255
3256 #[test]
3257 fn test_take_sliced_large_list() {
3258 test_take_sliced_list_generic::<i64>();
3259 }
3260
3261 #[test]
3262 fn test_take_sliced_list_with_value_nulls() {
3263 test_take_sliced_list_with_value_nulls_generic::<i32>();
3264 }
3265
3266 #[test]
3267 fn test_take_sliced_large_list_with_value_nulls() {
3268 test_take_sliced_list_with_value_nulls_generic::<i64>();
3269 }
3270
3271 #[test]
3272 fn test_take_sliced_list_memory_size() {
3273 fn check(parent: ArrayRef, unsliced: ArrayRef) {
3276 let sliced = parent.slice(500, 2);
3277 let indices = UInt32Array::from_iter_values((0..100).map(|i| i % 2));
3278 let actual = take(&sliced, &indices, None).unwrap();
3279 let expected = take(&unsliced, &indices, None).unwrap();
3280 assert_eq!(&actual, &expected);
3281 assert_eq!(
3282 actual.get_array_memory_size(),
3283 expected.get_array_memory_size()
3284 );
3285 }
3286
3287 let list = |rows: usize, values: ArrayRef| -> ArrayRef {
3289 let field = Arc::new(Field::new_list_field(values.data_type().clone(), false));
3290 let offsets = OffsetBuffer::from_repeated_length(10, rows);
3291 Arc::new(ListArray::new(field, offsets, values, None))
3292 };
3293 check(
3294 list(1000, Arc::new(Int64Array::from(vec![1; 10_000]))),
3295 list(2, Arc::new(Int64Array::from(vec![1; 20]))),
3296 );
3297 check(
3298 list(1000, Arc::new(StringArray::from(vec!["a"; 10_000]))),
3299 list(2, Arc::new(StringArray::from(vec!["a"; 20]))),
3300 );
3301 }
3302
3303 #[test]
3304 fn test_take_runs() {
3305 let logical_array: Vec<i32> = vec![1_i32, 1, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 2];
3306
3307 let mut builder = PrimitiveRunBuilder::<Int32Type, Int32Type>::new();
3308 builder.extend(logical_array.into_iter().map(Some));
3309 let run_array = builder.finish();
3310
3311 let take_indices: PrimitiveArray<Int32Type> =
3312 vec![7, 2, 3, 7, 11, 4, 6].into_iter().collect();
3313
3314 let take_out = take_run(&run_array, &take_indices).unwrap();
3315
3316 assert_eq!(take_out.len(), 7);
3317 assert_eq!(
3319 take_out.run_ends().values().len(),
3320 2,
3321 "expected two physical runs"
3322 );
3323 assert_eq!(take_out.run_ends().values(), &[5_i32, 7]);
3324
3325 let take_out_values = take_out.values().as_primitive::<Int32Type>();
3326 assert_eq!(take_out_values.values(), &[2, 1]);
3327 }
3328
3329 #[test]
3330 fn test_take_runs_null_indices() {
3331 let mut builder = PrimitiveRunBuilder::<Int32Type, Int32Type>::new();
3334 builder.extend([Some(10), Some(10), None, None, Some(99)]);
3335 let run_array = builder.finish();
3336
3337 let indices = Int32Array::from(vec![Some(0), None, Some(2), Some(3), Some(4)]);
3338 let taken = take(&run_array, &indices, None).unwrap();
3339 let run = taken.as_run::<Int32Type>();
3340 let logical: Vec<Option<i32>> = run.downcast::<Int32Array>().unwrap().into_iter().collect();
3341 assert_eq!(logical, vec![Some(10), None, None, None, Some(99)]);
3342 assert_eq!(run.run_ends().values(), &[1_i32, 4, 5]);
3343 }
3344
3345 #[test]
3346 fn test_take_runs_null_indices_non_nullable_values() {
3347 let run_array = unsafe {
3348 RunArray::<Int32Type>::new_unchecked(
3349 DataType::RunEndEncoded(
3350 Arc::new(Field::new("run_ends", DataType::Int32, false)),
3351 Arc::new(Field::new("values", DataType::Int32, false)),
3352 ),
3353 RunEndBuffer::new(vec![1_i32, 2].into(), 0, 2),
3354 Arc::new(Int32Array::from(vec![10, 20])),
3355 )
3356 };
3357 let indices = Int32Array::from(vec![Some(0), None]);
3358
3359 let error = take(&run_array, &indices, None).unwrap_err();
3360 assert_eq!(
3361 error.to_string(),
3362 "Compute error: Cannot take null indices from a RunEndEncoded array with a non-nullable values field"
3363 );
3364 }
3365
3366 #[test]
3367 fn test_take_runs_sliced() {
3368 let logical_array: Vec<i32> = vec![1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6];
3369
3370 let mut builder = PrimitiveRunBuilder::<Int32Type, Int32Type>::new();
3371 builder.extend(logical_array.into_iter().map(Some));
3372 let run_array = builder.finish();
3373
3374 let run_array = run_array.slice(4, 6); let take_indices: PrimitiveArray<Int32Type> = vec![0, 5, 5, 1, 4].into_iter().collect();
3377
3378 let result = take_run(&run_array, &take_indices).unwrap();
3379 let result = result.downcast::<Int32Array>().unwrap();
3380
3381 assert_eq!(
3383 result.run_ends().values().len(),
3384 4,
3385 "expected four physical runs"
3386 );
3387 assert_eq!(result.run_ends().values(), &[1_i32, 3, 4, 5]);
3388
3389 let expected = vec![3, 5, 5, 3, 4];
3390 let actual = result.into_iter().flatten().collect::<Vec<_>>();
3391
3392 assert_eq!(expected, actual);
3393 }
3394
3395 #[test]
3396 fn test_take_value_index_from_fixed_list() {
3397 let list = FixedSizeListArray::from_iter_primitive::<Int32Type, _, _>(
3398 vec![
3399 Some(vec![Some(1), Some(2), None]),
3400 Some(vec![Some(4), None, Some(6)]),
3401 None,
3402 Some(vec![None, Some(8), Some(9)]),
3403 ],
3404 3,
3405 );
3406
3407 let indices = UInt32Array::from(vec![2, 1, 0]);
3408 let indexed = take_value_indices_from_fixed_size_list(&list, &indices, 3).unwrap();
3409
3410 assert_eq!(indexed, UInt32Array::from(vec![6, 7, 8, 3, 4, 5, 0, 1, 2]));
3411
3412 let indices = UInt32Array::from(vec![3, 2, 1, 2, 0]);
3413 let indexed = take_value_indices_from_fixed_size_list(&list, &indices, 3).unwrap();
3414
3415 assert_eq!(
3416 indexed,
3417 UInt32Array::from(vec![9, 10, 11, 6, 7, 8, 3, 4, 5, 6, 7, 8, 0, 1, 2])
3418 );
3419 }
3420
3421 #[test]
3422 fn test_take_null_indices() {
3423 let indices = Int32Array::new(
3425 vec![1, 2, 400, 400].into(),
3426 Some(NullBuffer::from(vec![true, true, false, false])),
3427 );
3428 let values = Int32Array::from(vec![1, 23, 4, 5]);
3429 let r = take(&values, &indices, None).unwrap();
3430 let values = r
3431 .as_primitive::<Int32Type>()
3432 .into_iter()
3433 .collect::<Vec<_>>();
3434 assert_eq!(&values, &[Some(23), Some(4), None, None])
3435 }
3436
3437 #[test]
3438 fn test_take_fixed_size_list_null_indices() {
3439 let indices = Int32Array::from_iter([Some(0), None]);
3440 let values = Arc::new(Int32Array::from(vec![0, 1, 2, 3]));
3441 let arr_field = Arc::new(Field::new_list_field(values.data_type().clone(), true));
3442 let values = FixedSizeListArray::try_new(arr_field, 2, values, None).unwrap();
3443
3444 let r = take(&values, &indices, None).unwrap();
3445 let values = r
3446 .as_fixed_size_list()
3447 .values()
3448 .as_primitive::<Int32Type>()
3449 .into_iter()
3450 .collect::<Vec<_>>();
3451 assert_eq!(values, &[Some(0), Some(1), None, None])
3452 }
3453
3454 #[test]
3455 fn test_take_bytes_null_indices() {
3456 let indices = Int32Array::new(
3457 vec![0, 1, 400, 400].into(),
3458 Some(NullBuffer::from_iter(vec![true, true, false, false])),
3459 );
3460 let values = StringArray::from(vec![Some("foo"), None]);
3461 let r = take(&values, &indices, None).unwrap();
3462 let values = r.as_string::<i32>().iter().collect::<Vec<_>>();
3463 assert_eq!(&values, &[Some("foo"), None, None, None])
3464 }
3465
3466 #[test]
3467 fn test_take_union_sparse() {
3468 let structs = create_test_struct(vec![
3469 Some((Some(true), Some(42))),
3470 Some((Some(false), Some(28))),
3471 Some((Some(false), Some(19))),
3472 Some((Some(true), Some(31))),
3473 None,
3474 ]);
3475 let strings = StringArray::from(vec![Some("a"), None, Some("c"), None, Some("d")]);
3476 let type_ids = [1; 5].into_iter().collect::<ScalarBuffer<i8>>();
3477
3478 let union_fields = [
3479 (
3480 0,
3481 Arc::new(Field::new("f1", structs.data_type().clone(), true)),
3482 ),
3483 (
3484 1,
3485 Arc::new(Field::new("f2", strings.data_type().clone(), true)),
3486 ),
3487 ]
3488 .into_iter()
3489 .collect();
3490 let children = vec![Arc::new(structs) as Arc<dyn Array>, Arc::new(strings)];
3491 let array = UnionArray::try_new(union_fields, type_ids, None, children).unwrap();
3492
3493 let indices = vec![0, 3, 1, 0, 2, 4];
3494 let index = UInt32Array::from(indices.clone());
3495 let actual = take(&array, &index, None).unwrap();
3496 let actual = actual.as_any().downcast_ref::<UnionArray>().unwrap();
3497 let strings = actual.child(1);
3498 let strings = strings.as_any().downcast_ref::<StringArray>().unwrap();
3499
3500 let actual = strings.iter().collect::<Vec<_>>();
3501 let expected = vec![Some("a"), None, None, Some("a"), Some("c"), Some("d")];
3502 assert_eq!(expected, actual);
3503 }
3504
3505 #[test]
3506 fn test_take_union_dense() {
3507 let type_ids = vec![0, 1, 1, 0, 0, 1, 0];
3508 let offsets = vec![0, 0, 1, 1, 2, 2, 3];
3509 let ints = vec![10, 20, 30, 40];
3510 let strings = vec![Some("a"), None, Some("c"), Some("d")];
3511
3512 let indices = vec![0, 3, 1, 0, 2, 4];
3513
3514 let taken_type_ids = vec![0, 0, 1, 0, 1, 0];
3515 let taken_offsets = vec![0, 1, 0, 2, 1, 3];
3516 let taken_ints = vec![10, 20, 10, 30];
3517 let taken_strings = vec![Some("a"), None];
3518
3519 let type_ids = <ScalarBuffer<i8>>::from(type_ids);
3520 let offsets = <ScalarBuffer<i32>>::from(offsets);
3521 let ints = UInt32Array::from(ints);
3522 let strings = StringArray::from(strings);
3523
3524 let union_fields = [
3525 (
3526 0,
3527 Arc::new(Field::new("f1", ints.data_type().clone(), true)),
3528 ),
3529 (
3530 1,
3531 Arc::new(Field::new("f2", strings.data_type().clone(), true)),
3532 ),
3533 ]
3534 .into_iter()
3535 .collect();
3536
3537 let array = UnionArray::try_new(
3538 union_fields,
3539 type_ids,
3540 Some(offsets),
3541 vec![Arc::new(ints), Arc::new(strings)],
3542 )
3543 .unwrap();
3544
3545 let index = UInt32Array::from(indices);
3546
3547 let actual = take(&array, &index, None).unwrap();
3548 let actual = actual.as_any().downcast_ref::<UnionArray>().unwrap();
3549
3550 assert_eq!(actual.offsets(), Some(&ScalarBuffer::from(taken_offsets)));
3551 assert_eq!(actual.type_ids(), &ScalarBuffer::from(taken_type_ids));
3552 assert_eq!(
3553 UInt32Array::from(actual.child(0).to_data()),
3554 UInt32Array::from(taken_ints)
3555 );
3556 assert_eq!(
3557 StringArray::from(actual.child(1).to_data()),
3558 StringArray::from(taken_strings)
3559 );
3560 }
3561
3562 fn union_i32_logical(array: &UnionArray) -> Vec<Option<i32>> {
3563 (0..array.len())
3564 .map(|i| {
3565 let child = array.child(array.type_id(i)).as_primitive::<Int32Type>();
3566 let offset = array.value_offset(i);
3567 if child.is_null(offset) {
3568 None
3569 } else {
3570 Some(child.value(offset))
3571 }
3572 })
3573 .collect()
3574 }
3575
3576 #[test]
3577 fn test_take_union_dense_null_indices() {
3578 let fields =
3581 UnionFields::try_new(vec![5], vec![Field::new("i", DataType::Int32, true)]).unwrap();
3582 let dense = UnionArray::try_new(
3583 fields.clone(),
3584 ScalarBuffer::from(vec![5_i8, 5, 5]),
3585 Some(ScalarBuffer::from(vec![0_i32, 1, 2])),
3586 vec![Arc::new(Int32Array::from(vec![1, 2, 3]))],
3587 )
3588 .unwrap();
3589 let sparse = UnionArray::try_new(
3590 fields,
3591 ScalarBuffer::from(vec![5_i8, 5, 5]),
3592 None,
3593 vec![Arc::new(Int32Array::from(vec![1, 2, 3]))],
3594 )
3595 .unwrap();
3596
3597 let indices = UInt32Array::new(
3600 ScalarBuffer::from(vec![0_u32, 99, 2]),
3601 Some(NullBuffer::from(vec![true, false, true])),
3602 );
3603 let dense_taken = take(&dense, &indices, None).unwrap();
3604 let sparse_taken = take(&sparse, &indices, None).unwrap();
3605 let dense_logical = union_i32_logical(dense_taken.as_any().downcast_ref().unwrap());
3606 let sparse_logical = union_i32_logical(sparse_taken.as_any().downcast_ref().unwrap());
3607
3608 assert_eq!(dense_logical, vec![Some(1), None, Some(3)]);
3609 assert_eq!(dense_logical, sparse_logical);
3610 }
3611
3612 #[test]
3613 fn test_take_dense_union_null_indices_uses_nullable_field() {
3614 let fields = UnionFields::try_new(
3615 vec![0, 1],
3616 vec![
3617 Field::new("non_nullable", DataType::Int32, false),
3618 Field::new("nullable", DataType::Int32, true),
3619 ],
3620 )
3621 .unwrap();
3622 let union = UnionArray::try_new(
3623 fields,
3624 ScalarBuffer::from(vec![0_i8]),
3625 Some(ScalarBuffer::from(vec![0_i32])),
3626 vec![
3627 Arc::new(Int32Array::from(vec![10])),
3628 Arc::new(Int32Array::from(vec![20])),
3629 ],
3630 )
3631 .unwrap();
3632
3633 let taken = take(&union, &UInt32Array::from(vec![None]), None).unwrap();
3634 let taken = taken.as_union();
3635 assert_eq!(taken.type_id(0), 1);
3636 assert!(taken.child(1).is_null(0));
3637 }
3638
3639 #[test]
3640 fn test_take_sparse_union_null_indices_uses_nullable_field() {
3641 let fields = UnionFields::try_new(
3642 vec![0, 1],
3643 vec![
3644 Field::new("non_nullable", DataType::Int32, false),
3645 Field::new("nullable", DataType::Int32, true),
3646 ],
3647 )
3648 .unwrap();
3649 let union = UnionArray::try_new(
3650 fields,
3651 ScalarBuffer::from(vec![0_i8]),
3652 None,
3653 vec![
3654 Arc::new(Int32Array::from(vec![10])),
3655 Arc::new(Int32Array::from(vec![20])),
3656 ],
3657 )
3658 .unwrap();
3659
3660 let taken = take(&union, &UInt32Array::from(vec![Some(0), None]), None).unwrap();
3661 let taken = taken.as_union();
3662 assert_eq!(taken.type_ids(), &ScalarBuffer::from(vec![0_i8, 1]));
3663 assert_eq!(taken.logical_null_count(), 1);
3664 assert_eq!(
3665 taken
3666 .child(0)
3667 .as_primitive::<Int32Type>()
3668 .iter()
3669 .collect::<Vec<_>>(),
3670 vec![Some(10), Some(10)]
3671 );
3672 assert_eq!(
3673 taken
3674 .child(1)
3675 .as_primitive::<Int32Type>()
3676 .iter()
3677 .collect::<Vec<_>>(),
3678 vec![Some(20), None]
3679 );
3680 }
3681
3682 #[test]
3683 fn test_take_sparse_union_null_indices_no_nullable_fields() {
3684 let fields = UnionFields::try_new(
3685 vec![0, 1],
3686 vec![
3687 Field::new("a", DataType::Int32, false),
3688 Field::new("b", DataType::Int32, false),
3689 ],
3690 )
3691 .unwrap();
3692 let union = UnionArray::try_new(
3693 fields,
3694 ScalarBuffer::from(vec![0_i8]),
3695 None,
3696 vec![
3697 Arc::new(Int32Array::from(vec![10])),
3698 Arc::new(Int32Array::from(vec![20])),
3699 ],
3700 )
3701 .unwrap();
3702
3703 let error = take(&union, &UInt32Array::from(vec![None]), None).unwrap_err();
3704 assert_eq!(
3705 error.to_string(),
3706 "Compute error: Cannot take null indices from a union with no field that can represent nulls"
3707 );
3708 }
3709
3710 #[test]
3711 fn test_take_empty_sparse_union_null_indices_mixed_nullability() {
3712 let fields = UnionFields::try_new(
3713 vec![0, 1],
3714 vec![
3715 Field::new("non_nullable", DataType::Int32, false),
3716 Field::new("nullable", DataType::Int32, true),
3717 ],
3718 )
3719 .unwrap();
3720 let union = UnionArray::try_new(
3721 fields,
3722 ScalarBuffer::<i8>::from(vec![]),
3723 None,
3724 vec![
3725 Arc::new(Int32Array::from(Vec::<i32>::new())),
3726 Arc::new(Int32Array::from(Vec::<i32>::new())),
3727 ],
3728 )
3729 .unwrap();
3730
3731 let taken = take(&union, &UInt32Array::from(vec![None]), None).unwrap();
3732 let taken = taken.as_union();
3733 assert_eq!(taken.len(), 1);
3734 assert_eq!(taken.type_id(0), 1);
3735 assert_eq!(taken.logical_null_count(), 1);
3736 assert!(!taken.child(0).is_null(0));
3737 assert!(taken.child(1).is_null(0));
3738 }
3739
3740 #[test]
3741 fn test_take_empty_union_without_null_indices() {
3742 let fields = UnionFields::try_new(vec![], Vec::<Field>::new()).unwrap();
3743 let indices = UInt32Array::from(Vec::<u32>::new());
3744
3745 let sparse = UnionArray::try_new(
3746 fields.clone(),
3747 ScalarBuffer::<i8>::from(vec![]),
3748 None,
3749 vec![],
3750 )
3751 .unwrap();
3752 let dense = UnionArray::try_new(
3753 fields,
3754 ScalarBuffer::<i8>::from(vec![]),
3755 Some(ScalarBuffer::<i32>::from(vec![])),
3756 vec![],
3757 )
3758 .unwrap();
3759
3760 for values in [&sparse, &dense] {
3761 let taken = take(values, &indices, None).unwrap();
3762 assert_eq!(taken.len(), 0);
3763 assert_eq!(taken.data_type(), values.data_type());
3764 }
3765 }
3766
3767 #[test]
3768 fn test_take_empty_union_with_null_indices() {
3769 let fields = UnionFields::try_new(vec![], Vec::<Field>::new()).unwrap();
3770 let indices = UInt32Array::from(vec![None]);
3771
3772 let sparse = UnionArray::try_new(
3773 fields.clone(),
3774 ScalarBuffer::<i8>::from(vec![]),
3775 None,
3776 vec![],
3777 )
3778 .unwrap();
3779 let dense = UnionArray::try_new(
3780 fields,
3781 ScalarBuffer::<i8>::from(vec![]),
3782 Some(ScalarBuffer::<i32>::from(vec![])),
3783 vec![],
3784 )
3785 .unwrap();
3786
3787 for values in [&sparse, &dense] {
3788 let error = take(values, &indices, None).unwrap_err();
3789 assert_eq!(
3790 error.to_string(),
3791 "Compute error: Cannot take null indices from a union with no field that can represent nulls"
3792 );
3793 }
3794 }
3795
3796 fn inner_union_no_nullable_children(mode: UnionMode) -> (UnionFields, UnionArray) {
3797 let fields = UnionFields::try_new(
3798 vec![0, 1],
3799 vec![
3800 Field::new("a", DataType::Int32, false),
3801 Field::new("b", DataType::Int32, false),
3802 ],
3803 )
3804 .unwrap();
3805 let children: Vec<ArrayRef> = vec![
3806 Arc::new(Int32Array::from(vec![10])),
3807 Arc::new(Int32Array::from(vec![20])),
3808 ];
3809 let array = match mode {
3810 UnionMode::Sparse => UnionArray::try_new(
3811 fields.clone(),
3812 ScalarBuffer::from(vec![0_i8]),
3813 None,
3814 children,
3815 )
3816 .unwrap(),
3817 UnionMode::Dense => UnionArray::try_new(
3818 fields.clone(),
3819 ScalarBuffer::from(vec![0_i8]),
3820 Some(ScalarBuffer::from(vec![0_i32])),
3821 children,
3822 )
3823 .unwrap(),
3824 };
3825 (fields, array)
3826 }
3827
3828 #[test]
3829 fn test_take_union_null_indices_skips_nested_union_without_nullable_children() {
3830 for mode in [UnionMode::Sparse, UnionMode::Dense] {
3834 let (inner_fields, inner) = inner_union_no_nullable_children(mode);
3835 let outer_fields = UnionFields::try_new(
3836 vec![0, 1],
3837 vec![
3838 Field::new("inner", DataType::Union(inner_fields, mode), true),
3839 Field::new("i", DataType::Int32, true),
3840 ],
3841 )
3842 .unwrap();
3843 let children: Vec<ArrayRef> =
3844 vec![Arc::new(inner), Arc::new(Int32Array::from(vec![30]))];
3845 let outer = match mode {
3846 UnionMode::Sparse => UnionArray::try_new(
3847 outer_fields,
3848 ScalarBuffer::from(vec![1_i8]),
3849 None,
3850 children,
3851 )
3852 .unwrap(),
3853 UnionMode::Dense => UnionArray::try_new(
3854 outer_fields,
3855 ScalarBuffer::from(vec![1_i8]),
3856 Some(ScalarBuffer::from(vec![0_i32])),
3857 children,
3858 )
3859 .unwrap(),
3860 };
3861
3862 let taken = take(&outer, &UInt32Array::from(vec![None]), None).unwrap();
3863 let taken = taken.as_union();
3864 assert_eq!(taken.type_id(0), 1, "{mode:?}");
3865 assert!(taken.child(1).is_null(0), "{mode:?}");
3866 assert_eq!(taken.logical_null_count(), 1, "{mode:?}");
3867 }
3868 }
3869
3870 #[test]
3871 fn test_take_union_null_indices_nested_union_cannot_represent_null() {
3872 for mode in [UnionMode::Sparse, UnionMode::Dense] {
3875 let (inner_fields, inner) = inner_union_no_nullable_children(mode);
3876 let outer_fields = UnionFields::try_new(
3877 vec![0],
3878 vec![Field::new(
3879 "inner",
3880 DataType::Union(inner_fields, mode),
3881 true,
3882 )],
3883 )
3884 .unwrap();
3885 let children: Vec<ArrayRef> = vec![Arc::new(inner)];
3886 let outer = match mode {
3887 UnionMode::Sparse => UnionArray::try_new(
3888 outer_fields,
3889 ScalarBuffer::from(vec![0_i8]),
3890 None,
3891 children,
3892 )
3893 .unwrap(),
3894 UnionMode::Dense => UnionArray::try_new(
3895 outer_fields,
3896 ScalarBuffer::from(vec![0_i8]),
3897 Some(ScalarBuffer::from(vec![0_i32])),
3898 children,
3899 )
3900 .unwrap(),
3901 };
3902
3903 let error = take(&outer, &UInt32Array::from(vec![None]), None).unwrap_err();
3904 assert_eq!(
3905 error.to_string(),
3906 "Compute error: Cannot take null indices from a union with no field that can represent nulls"
3907 );
3908 }
3909 }
3910
3911 #[test]
3912 fn test_take_union_null_indices_skips_ree_with_non_nullable_values() {
3913 let run_array = unsafe {
3916 RunArray::<Int32Type>::new_unchecked(
3917 DataType::RunEndEncoded(
3918 Arc::new(Field::new("run_ends", DataType::Int32, false)),
3919 Arc::new(Field::new("values", DataType::Int32, false)),
3920 ),
3921 RunEndBuffer::new(vec![1_i32].into(), 0, 1),
3922 Arc::new(Int32Array::from(vec![10])),
3923 )
3924 };
3925 let fields = UnionFields::try_new(
3926 vec![0, 1],
3927 vec![
3928 Field::new("ree", run_array.data_type().clone(), true),
3929 Field::new("i", DataType::Int32, true),
3930 ],
3931 )
3932 .unwrap();
3933 let union = UnionArray::try_new(
3934 fields,
3935 ScalarBuffer::from(vec![1_i8]),
3936 None,
3937 vec![
3938 Arc::new(run_array) as ArrayRef,
3939 Arc::new(Int32Array::from(vec![30])),
3940 ],
3941 )
3942 .unwrap();
3943
3944 let taken = take(&union, &UInt32Array::from(vec![None]), None).unwrap();
3945 let taken = taken.as_union();
3946 assert_eq!(taken.type_id(0), 1);
3947 assert!(taken.child(1).is_null(0));
3948 assert_eq!(taken.logical_null_count(), 1);
3949 }
3950
3951 #[test]
3952 fn test_take_union_dense_using_builder() {
3953 let mut builder = UnionBuilder::new_dense();
3954
3955 builder.append::<Int32Type>("a", 1).unwrap();
3956 builder.append::<Float64Type>("b", 3.0).unwrap();
3957 builder.append::<Int32Type>("a", 4).unwrap();
3958 builder.append::<Int32Type>("a", 5).unwrap();
3959 builder.append::<Float64Type>("b", 2.0).unwrap();
3960
3961 let union = builder.build().unwrap();
3962
3963 let indices = UInt32Array::from(vec![2, 0, 1, 2]);
3964
3965 let mut builder = UnionBuilder::new_dense();
3966
3967 builder.append::<Int32Type>("a", 4).unwrap();
3968 builder.append::<Int32Type>("a", 1).unwrap();
3969 builder.append::<Float64Type>("b", 3.0).unwrap();
3970 builder.append::<Int32Type>("a", 4).unwrap();
3971
3972 let taken = builder.build().unwrap();
3973
3974 assert_eq!(
3975 taken.to_data(),
3976 take(&union, &indices, None).unwrap().to_data()
3977 );
3978 }
3979
3980 #[test]
3981 fn test_take_union_dense_all_match_issue_6206() {
3982 let fields = UnionFields::from_fields(vec![Field::new("a", DataType::Int64, false)]);
3983 let ints = Arc::new(Int64Array::from(vec![1, 2, 3, 4, 5]));
3984
3985 let array = UnionArray::try_new(
3986 fields,
3987 ScalarBuffer::from(vec![0_i8, 0, 0, 0, 0]),
3988 Some(ScalarBuffer::from_iter(0_i32..5)),
3989 vec![ints],
3990 )
3991 .unwrap();
3992
3993 let indices = Int64Array::from(vec![0, 2, 4]);
3994 let array = take(&array, &indices, None).unwrap();
3995 assert_eq!(array.len(), 3);
3996 }
3997
3998 fn offset_overflow_fixture() -> (StringArray, usize) {
4003 let value_len = 1_000_000;
4004 let values = StringArray::from(vec![Some("a".repeat(value_len))]);
4005 let n = i32::MAX as usize / value_len + 1;
4006 (values, n)
4007 }
4008
4009 #[test]
4010 fn test_take_bytes_offset_overflow() {
4011 let (values, n) = offset_overflow_fixture();
4012 let indices = Int32Array::from(vec![0; n]);
4013 assert!(matches!(
4014 take(&values, &indices, None),
4015 Err(ArrowError::OffsetOverflowError(_))
4016 ));
4017 }
4018
4019 #[test]
4022 fn test_take_bytes_offset_overflow_nullable() {
4023 let (values, n) = offset_overflow_fixture();
4024 let validity =
4027 NullBuffer::from_iter(std::iter::once(false).chain(std::iter::repeat_n(true, n)));
4028 let indices = Int32Array::new(vec![0i32; n + 1].into(), Some(validity));
4029
4030 assert!(matches!(
4031 take(&values, &indices, None),
4032 Err(ArrowError::OffsetOverflowError(_))
4033 ));
4034 }
4035
4036 #[test]
4037 fn test_take_run_empty_indices() {
4038 let mut builder = PrimitiveRunBuilder::<Int32Type, Int32Type>::new();
4039 builder.extend([Some(1), Some(1), Some(2), Some(2)]);
4040 let run_array = builder.finish();
4041
4042 let logical_indices: PrimitiveArray<Int32Type> = PrimitiveArray::from(Vec::<i32>::new());
4043
4044 let result = take_impl::<_, true>(&run_array, &logical_indices)
4045 .expect("take_run with empty indices");
4046
4047 assert_eq!(result.len(), 0);
4049 assert_eq!(result.null_count(), 0);
4050
4051 let run_result = result
4054 .as_any()
4055 .downcast_ref::<RunArray<Int32Type>>()
4056 .expect("result should be a RunArray");
4057 assert_eq!(run_result.run_ends().len(), 0);
4058 assert_eq!(run_result.values().len(), 0);
4059 }
4060
4061 #[test]
4062 fn test_take_run_end_encoded_merges_identical_runs() {
4063 let mut builder = PrimitiveRunBuilder::<Int32Type, Int32Type>::new();
4067 builder.extend([1, 1, 0, 0, 1, 1].into_iter().map(Some));
4068 let ree = builder.finish();
4069
4070 let indexes = Int32Array::from_iter_values(vec![0, 1, 4, 5]);
4071 let result = take(&ree, &indexes, None).unwrap();
4072 let result = result
4073 .as_run::<Int32Type>()
4074 .downcast::<Int32Array>()
4075 .unwrap();
4076
4077 assert_eq!(
4079 result.run_ends().values().len(),
4080 1,
4081 "expected a single physical run"
4082 );
4083 assert_eq!(result.run_ends().values(), &[4_i32]);
4084
4085 let actual = result.into_iter().flatten().collect::<Vec<_>>();
4086 assert_eq!(actual, vec![1, 1, 1, 1]);
4087 }
4088
4089 #[test]
4090 fn test_take_run_end_encoded_merges_identical_string_runs() {
4091 let mut builder = StringRunBuilder::<Int32Type>::new();
4092 builder.extend(
4093 ["bob", "bob", "alice", "alice", "bob", "bob"]
4094 .into_iter()
4095 .map(Some),
4096 );
4097 let ree = builder.finish();
4098
4099 let indexes = Int32Array::from_iter_values(vec![0, 1, 4, 5]);
4100 let result = take(&ree, &indexes, None).unwrap();
4101 let result = result
4102 .as_run::<Int32Type>()
4103 .downcast::<StringArray>()
4104 .unwrap();
4105
4106 assert_eq!(
4108 result.run_ends().values().len(),
4109 1,
4110 "expected a single physical run"
4111 );
4112 assert_eq!(result.run_ends().values(), &[4_i32]);
4113
4114 let actual = result.into_iter().flatten().collect::<Vec<_>>();
4115 assert_eq!(actual, vec!["bob", "bob", "bob", "bob"]);
4116 }
4117
4118 #[test]
4119 fn test_take_run_end_encoded_mixed_runs() {
4120 let mut builder = StringRunBuilder::<Int32Type>::new();
4123 builder.extend(
4124 ["bob", "bob", "alice", "alice", "bob", "bob", "eve", "eve"]
4125 .into_iter()
4126 .map(Some),
4127 );
4128 let ree = builder.finish();
4129
4130 let indexes = Int32Array::from_iter_values(vec![0, 0, 1, 4, 5, 2, 3, 2, 6, 7, 6]);
4132 let result = take(&ree, &indexes, None).unwrap();
4133 let result = result
4134 .as_run::<Int32Type>()
4135 .downcast::<StringArray>()
4136 .unwrap();
4137
4138 println!("run_ends_raw: {:?}", result.run_ends());
4141 println!("run_ends: {:?}", result.run_ends().values());
4142 println!("values : {:?}", result.values());
4143 assert_eq!(
4144 result.run_ends().values().len(),
4145 3,
4146 "expected three physical runs"
4147 );
4148 assert_eq!(result.run_ends().values(), &[5_i32, 8, 11]);
4149
4150 let actual = result.into_iter().flatten().collect::<Vec<_>>();
4151 assert_eq!(
4152 actual,
4153 vec![
4154 "bob", "bob", "bob", "bob", "bob", "alice", "alice", "alice", "eve", "eve", "eve"
4155 ]
4156 );
4157 }
4158
4159 #[test]
4161 fn test_take_fixed_size_list_parent_nulls() {
4162 let list = FixedSizeListArray::from_iter_primitive::<Int32Type, _, _>(
4163 vec![
4164 Some(vec![Some(1), Some(2)]),
4165 None,
4166 Some(vec![Some(5), Some(6)]),
4167 ],
4168 2,
4169 );
4170
4171 let indices = UInt32Array::from(vec![2, 1, 0]);
4172 let result = take(&list, &indices, None).unwrap();
4173 let result = result.as_fixed_size_list();
4174
4175 assert_eq!(result.len(), 3);
4176 assert!(result.is_valid(0));
4177 assert!(result.is_null(1));
4178 assert!(result.is_valid(2));
4179
4180 let child = result.values().as_primitive::<Int32Type>();
4181 assert_eq!(child.value(0), 5);
4182 assert_eq!(child.value(1), 6);
4183 assert!(child.is_null(2));
4184 assert!(child.is_null(3));
4185 assert_eq!(child.value(4), 1);
4186 assert_eq!(child.value(5), 2);
4187 }
4188
4189 #[test]
4190 fn test_take_zero_sized_fixed_size_list() {
4191 let input = FixedSizeListArray::try_new_with_length(
4192 Field::new_list_field(DataType::Int32, true).into(),
4193 0,
4194 Arc::new(Int32Array::new_null(0)),
4195 None,
4196 3,
4197 )
4198 .unwrap();
4199
4200 let indices = UInt32Array::from(vec![2, 0]);
4201 let result = take(&input, &indices, None).unwrap();
4202
4203 assert_eq!(result.len(), 2);
4204 }
4205
4206 #[test]
4207 fn test_take_zero_sized_fixed_size_binary() {
4208 let input =
4209 FixedSizeBinaryArray::try_new_with_len(0, Buffer::from(Vec::<u8>::new()), None, 3)
4210 .unwrap();
4211
4212 let indices = UInt32Array::from(vec![2, 0]);
4213 let result = take(&input, &indices, None).unwrap();
4214
4215 assert_eq!(result.len(), 2);
4216 }
4217
4218 fn non_nullable_columns() -> Vec<ArrayRef> {
4220 vec![
4221 Arc::new(Int32Array::from(vec![1, 2, 3])),
4222 Arc::new(StringArray::from(vec!["a", "bb", "ccc"])),
4223 Arc::new(DictionaryArray::<Int8Type>::from_iter(["x", "y", "x"])),
4224 Arc::new(StructArray::from(vec![(
4225 Arc::new(Field::new("c", DataType::Int32, false)),
4226 Arc::new(Int32Array::from(vec![1, 2, 3])) as ArrayRef,
4227 )])),
4228 Arc::new(FixedSizeListArray::from_iter_primitive::<Int32Type, _, _>(
4229 vec![
4230 Some(vec![Some(1)]),
4231 Some(vec![Some(2)]),
4232 Some(vec![Some(3)]),
4233 ],
4234 1,
4235 )),
4236 ]
4237 }
4238
4239 fn batch_with_non_nullable(column: ArrayRef) -> RecordBatch {
4241 let schema = Schema::new(vec![
4242 Field::new("n", DataType::Int32, true),
4243 Field::new("a", column.data_type().clone(), false),
4244 ]);
4245 let n = Arc::new(Int32Array::from(vec![Some(1), None, Some(3)]));
4246 RecordBatch::try_new(Arc::new(schema), vec![n, column]).unwrap()
4247 }
4248
4249 #[test]
4250 fn test_take_record_batch_null_index_non_nullable_column() {
4251 let indices = UInt32Array::from(vec![Some(2), None]);
4252 for column in non_nullable_columns() {
4253 let batch = batch_with_non_nullable(column);
4254 let err = take_record_batch(&batch, &indices).unwrap_err();
4255 assert_eq!(
4256 err.to_string(),
4257 "Invalid argument error: Column 'a' is declared as non-nullable but contains null values",
4258 "{}",
4259 batch.column(1).data_type()
4260 );
4261 }
4262 }
4263
4264 #[test]
4265 fn test_take_record_batch_non_nullable_column() {
4266 let indices = [
4267 UInt32Array::from(vec![2, 0, 2]),
4268 UInt32Array::new(vec![2, 0].into(), Some(NullBuffer::new_valid(2))),
4270 ];
4271 for column in non_nullable_columns() {
4272 let batch = batch_with_non_nullable(column);
4273 for indices in &indices {
4274 let taken = take_record_batch(&batch, indices).unwrap();
4275
4276 assert_eq!(taken.schema(), batch.schema());
4277 for (taken, column) in taken.columns().iter().zip(batch.columns()) {
4278 assert_eq!(taken, &take(column, indices, None).unwrap());
4279 }
4280 }
4281 }
4282 }
4283
4284 #[test]
4285 fn test_take_record_batch_no_columns_row_count() {
4286 let options = RecordBatchOptions::new().with_row_count(Some(3));
4287 let batch =
4288 RecordBatch::try_new_with_options(Arc::new(Schema::empty()), vec![], &options).unwrap();
4289
4290 let indices = UInt32Array::from(vec![Some(2), None, Some(0), Some(2)]);
4291 let taken = take_record_batch(&batch, &indices).unwrap();
4292 assert_eq!(taken.num_rows(), 4);
4293 }
4294
4295 fn zero_width_columns(len: usize) -> Vec<ArrayRef> {
4297 vec![
4298 Arc::new(NullArray::new(len)),
4299 Arc::new(StructArray::new_empty_fields(len, None)),
4300 Arc::new(
4301 FixedSizeListArray::try_new_with_length(
4302 Field::new_list_field(DataType::Int32, true).into(),
4303 0,
4304 Arc::new(Int32Array::new_null(0)),
4305 None,
4306 len,
4307 )
4308 .unwrap(),
4309 ),
4310 Arc::new(
4311 FixedSizeBinaryArray::try_new_with_len(
4312 0,
4313 Buffer::from(Vec::<u8>::new()),
4314 None,
4315 len,
4316 )
4317 .unwrap(),
4318 ),
4319 ]
4320 }
4321
4322 fn batch_with_first_column(first: ArrayRef) -> RecordBatch {
4324 RecordBatch::try_from_iter_with_nullable([
4325 ("first", first, true),
4326 (
4327 "i",
4328 Arc::new(Int32Array::from(vec![Some(1), None, Some(3)])) as ArrayRef,
4329 true,
4330 ),
4331 (
4332 "s",
4333 Arc::new(StringArray::from(vec!["a", "bb", "ccc"])),
4334 true,
4335 ),
4336 (
4337 "l",
4338 Arc::new(ListArray::from_iter_primitive::<Int32Type, _, _>(vec![
4339 Some(vec![Some(1)]),
4340 None,
4341 Some(vec![Some(3), None]),
4342 ])),
4343 true,
4344 ),
4345 ])
4346 .unwrap()
4347 }
4348
4349 #[test]
4350 fn test_take_record_batch() {
4351 let first: ArrayRef = Arc::new(BooleanArray::from(vec![true, false, true]));
4352 let mut columns = vec![first];
4353 columns.extend(zero_width_columns(3));
4354 for first in columns {
4355 let batch = batch_with_first_column(first);
4356 let indices = UInt32Array::from(vec![Some(2), None, Some(0), Some(2)]);
4357 let taken = take_record_batch(&batch, &indices).unwrap();
4358
4359 assert_eq!(taken.schema(), batch.schema());
4360 assert_eq!(taken.num_rows(), 4);
4361 for (taken, column) in taken.columns().iter().zip(batch.columns()) {
4362 assert_eq!(taken, &take(column, &indices, None).unwrap());
4363 }
4364 }
4365 }
4366
4367 #[test]
4368 fn test_take_record_batch_out_of_bounds() {
4369 let indices: [ArrayRef; 5] = [
4370 Arc::new(UInt32Array::from(vec![0, 3])),
4372 Arc::new(UInt32Array::from(vec![None, Some(3)])),
4373 Arc::new(Int32Array::from(vec![-1])),
4374 Arc::new(Int8Array::from(vec![i8::MAX])),
4375 Arc::new(UInt64Array::from(vec![u64::MAX])),
4376 ];
4377 let first: ArrayRef = Arc::new(Int64Array::from(vec![1, 2, 3]));
4378 let mut columns = vec![first];
4379 columns.extend(zero_width_columns(3));
4380 for first in columns {
4381 let batch = batch_with_first_column(first);
4382 for indices in &indices {
4383 let err = take_record_batch(&batch, indices).unwrap_err();
4384 assert!(
4385 err.to_string().contains("Array index out of bounds"),
4386 "{}: {err}",
4387 batch.column(0).data_type()
4388 );
4389 }
4390 }
4391 }
4392
4393 #[test]
4394 fn test_take_record_batch_null_index_out_of_bounds_value() {
4395 let indices = UInt32Array::new(
4397 vec![2, u32::MAX, 0].into(),
4398 Some(NullBuffer::from(vec![true, false, true])),
4399 );
4400 for first in zero_width_columns(3) {
4401 let batch = batch_with_first_column(first);
4402 let taken = take_record_batch(&batch, &indices).unwrap();
4403
4404 assert_eq!(taken.num_rows(), 3);
4405 assert_eq!(
4406 taken.column(1).as_primitive::<Int32Type>(),
4407 &Int32Array::from(vec![Some(3), None, Some(1)])
4408 );
4409 assert_eq!(
4410 taken.column(2).as_string::<i32>(),
4411 &StringArray::from(vec![Some("ccc"), None, Some("a")])
4412 );
4413 }
4414 }
4415
4416 #[test]
4417 fn test_take_record_batch_empty() {
4418 let batch = batch_with_first_column(Arc::new(NullArray::new(3))).slice(0, 0);
4419
4420 let taken = take_record_batch(&batch, &UInt32Array::from(Vec::<u32>::new())).unwrap();
4421 assert_eq!(taken.num_rows(), 0);
4422 assert_eq!(taken.schema(), batch.schema());
4423
4424 let taken = take_record_batch(&batch, &UInt32Array::from(vec![None, None])).unwrap();
4425 assert_eq!(taken.num_rows(), 2);
4426 assert_eq!(taken.column(1).null_count(), 2);
4427
4428 assert!(take_record_batch(&batch, &UInt32Array::from(vec![0])).is_err());
4429 }
4430
4431 #[test]
4432 fn test_take_record_batch_no_columns() {
4433 let options = RecordBatchOptions::new().with_row_count(Some(3));
4434 let batch =
4435 RecordBatch::try_new_with_options(Arc::new(Schema::empty()), vec![], &options).unwrap();
4436
4437 let taken = take_record_batch(&batch, &UInt32Array::from(vec![2, 0, 2, 1])).unwrap();
4438 assert_eq!(taken.num_rows(), 4);
4439
4440 assert!(take_record_batch(&batch, &UInt32Array::from(vec![3])).is_err());
4441 }
4442}