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