1use crate::filter::{SlicesIterator, prep_null_mask_filter};
21use arrow_array::cast::AsArray;
22use arrow_array::types::{
23 BinaryType, BinaryViewType, ByteArrayType, ByteViewType, LargeBinaryType, LargeUtf8Type,
24 StringViewType, Utf8Type,
25};
26use arrow_array::*;
27use arrow_buffer::{
28 BooleanBuffer, Buffer, MutableBuffer, NullBuffer, OffsetBuffer, OffsetBufferBuilder,
29 ScalarBuffer, ToByteSlice,
30};
31use arrow_data::transform::MutableArrayData;
32use arrow_data::{ArrayData, ByteView};
33use arrow_schema::{ArrowError, DataType};
34use std::fmt::{Debug, Formatter};
35use std::hash::Hash;
36use std::marker::PhantomData;
37use std::ops::Not;
38use std::sync::{Arc, OnceLock};
39
40pub fn zip(
100 mask: &BooleanArray,
101 truthy: &dyn Datum,
102 falsy: &dyn Datum,
103) -> Result<ArrayRef, ArrowError> {
104 let (truthy_array, truthy_is_scalar) = truthy.get();
105 let (falsy_array, falsy_is_scalar) = falsy.get();
106
107 if falsy_is_scalar && truthy_is_scalar {
108 let zipper = ScalarZipper::try_new(truthy, falsy)?;
109 return zipper.zip_impl.create_output(mask);
110 }
111
112 let truthy = truthy_array;
113 let falsy = falsy_array;
114
115 if truthy.data_type() != falsy.data_type() {
116 return Err(ArrowError::InvalidArgumentError(
117 "arguments need to have the same data type".into(),
118 ));
119 }
120
121 if truthy_is_scalar && truthy.len() != 1 {
122 return Err(ArrowError::InvalidArgumentError(
123 "scalar arrays must have 1 element".into(),
124 ));
125 }
126 if !truthy_is_scalar && truthy.len() != mask.len() {
127 return Err(ArrowError::InvalidArgumentError(
128 "all arrays should have the same length".into(),
129 ));
130 }
131 if falsy_is_scalar && falsy.len() != 1 {
132 return Err(ArrowError::InvalidArgumentError(
133 "scalar arrays must have 1 element".into(),
134 ));
135 }
136 if !falsy_is_scalar && falsy.len() != mask.len() {
137 return Err(ArrowError::InvalidArgumentError(
138 "all arrays should have the same length".into(),
139 ));
140 }
141
142 let falsy = falsy.to_data();
143 let truthy = truthy.to_data();
144
145 zip_impl(mask, &truthy, truthy_is_scalar, &falsy, falsy_is_scalar)
146}
147
148fn count_true_runs(mask: &BooleanBuffer) -> usize {
149 let mut slices = 0;
150 let mut previous = 0;
151 for chunk in mask.bit_chunks().iter_padded() {
152 let starts = chunk & !((chunk << 1) | previous);
153 slices += starts.count_ones() as usize;
154 previous = chunk >> 63;
155 }
156 slices
157}
158
159fn should_use_interleave(mask: &BooleanBuffer) -> bool {
160 const MIN_LEN: usize = 1024;
161
162 mask.len() >= MIN_LEN && count_true_runs(mask) > mask.len() / 8
166}
167
168fn interleave_arrays(
169 mask: &BooleanBuffer,
170 truthy: &ArrayData,
171 falsy: &ArrayData,
172) -> Result<ArrayRef, ArrowError> {
173 let truthy = make_array(truthy.clone());
174 let falsy = make_array(falsy.clone());
175 let indices: Vec<_> = mask
176 .iter()
177 .enumerate()
178 .map(|(idx, selected)| (usize::from(!selected), idx))
179 .collect();
180 crate::interleave::interleave(&[truthy.as_ref(), falsy.as_ref()], &indices)
181}
182
183fn zip_impl(
184 mask: &BooleanArray,
185 truthy: &ArrayData,
186 truthy_is_scalar: bool,
187 falsy: &ArrayData,
188 falsy_is_scalar: bool,
189) -> Result<ArrayRef, ArrowError> {
190 let mask_buffer = maybe_prep_null_mask_filter(mask);
191 if !truthy_is_scalar && !falsy_is_scalar && should_use_interleave(&mask_buffer) {
192 return interleave_arrays(&mask_buffer, truthy, falsy);
193 }
194
195 let mut mutable = MutableArrayData::new(vec![truthy, falsy], false, truthy.len());
196
197 let mut filled = 0;
202
203 for (start, end) in SlicesIterator::from(&mask_buffer) {
204 if start > filled {
206 if falsy_is_scalar {
207 for _ in filled..start {
208 mutable.try_extend(1, 0, 1)?;
210 }
211 } else {
212 mutable.try_extend(1, filled, start)?;
213 }
214 }
215 if truthy_is_scalar {
217 for _ in start..end {
218 mutable.try_extend(0, 0, 1)?;
220 }
221 } else {
222 mutable.try_extend(0, start, end)?;
223 }
224 filled = end;
225 }
226 if filled < mask.len() {
228 if falsy_is_scalar {
229 for _ in filled..mask.len() {
230 mutable.try_extend(1, 0, 1)?;
232 }
233 } else {
234 mutable.try_extend(1, filled, mask.len())?;
235 }
236 }
237
238 let data = mutable.freeze();
239 Ok(make_array(data))
240}
241
242#[derive(Debug, Clone)]
264pub struct ScalarZipper {
265 zip_impl: Arc<dyn ZipImpl>,
266}
267
268impl ScalarZipper {
269 pub fn try_new(truthy: &dyn Datum, falsy: &dyn Datum) -> Result<Self, ArrowError> {
277 let (truthy, truthy_is_scalar) = truthy.get();
278 let (falsy, falsy_is_scalar) = falsy.get();
279
280 if truthy.data_type() != falsy.data_type() {
281 return Err(ArrowError::InvalidArgumentError(
282 "arguments need to have the same data type".into(),
283 ));
284 }
285
286 if !truthy_is_scalar {
287 return Err(ArrowError::InvalidArgumentError(
288 "only scalar arrays are supported".into(),
289 ));
290 }
291
292 if !falsy_is_scalar {
293 return Err(ArrowError::InvalidArgumentError(
294 "only scalar arrays are supported".into(),
295 ));
296 }
297
298 if truthy.len() != 1 {
299 return Err(ArrowError::InvalidArgumentError(
300 "scalar arrays must have 1 element".into(),
301 ));
302 }
303 if falsy.len() != 1 {
304 return Err(ArrowError::InvalidArgumentError(
305 "scalar arrays must have 1 element".into(),
306 ));
307 }
308
309 macro_rules! primitive_size_helper {
310 ($t:ty) => {
311 Arc::new(PrimitiveScalarImpl::<$t>::new(truthy, falsy)) as Arc<dyn ZipImpl>
312 };
313 }
314
315 let zip_impl = downcast_primitive! {
316 truthy.data_type() => (primitive_size_helper),
317 DataType::Utf8 => {
318 Arc::new(BytesScalarImpl::<Utf8Type>::new(truthy, falsy)) as Arc<dyn ZipImpl>
319 },
320 DataType::LargeUtf8 => {
321 Arc::new(BytesScalarImpl::<LargeUtf8Type>::new(truthy, falsy)) as Arc<dyn ZipImpl>
322 },
323 DataType::Binary => {
324 Arc::new(BytesScalarImpl::<BinaryType>::new(truthy, falsy)) as Arc<dyn ZipImpl>
325 },
326 DataType::LargeBinary => {
327 Arc::new(BytesScalarImpl::<LargeBinaryType>::new(truthy, falsy)) as Arc<dyn ZipImpl>
328 },
329 DataType::Utf8View => {
330 Arc::new(ByteViewScalarImpl::<StringViewType>::new(truthy, falsy)) as Arc<dyn ZipImpl>
331 },
332 DataType::BinaryView => {
333 Arc::new(ByteViewScalarImpl::<BinaryViewType>::new(truthy, falsy)) as Arc<dyn ZipImpl>
334 },
335 _ => {
336 Arc::new(FallbackImpl::new(truthy, falsy)) as Arc<dyn ZipImpl>
337 },
338 };
339
340 Ok(Self { zip_impl })
341 }
342
343 pub fn zip(&self, mask: &BooleanArray) -> Result<ArrayRef, ArrowError> {
346 self.zip_impl.create_output(mask)
347 }
348}
349
350trait ZipImpl: Debug + Send + Sync {
352 fn create_output(&self, input: &BooleanArray) -> Result<ArrayRef, ArrowError>;
354}
355
356#[derive(Debug, PartialEq)]
357struct FallbackImpl {
358 truthy: ArrayData,
359 falsy: ArrayData,
360}
361
362impl FallbackImpl {
363 fn new(left: &dyn Array, right: &dyn Array) -> Self {
364 Self {
365 truthy: left.to_data(),
366 falsy: right.to_data(),
367 }
368 }
369}
370
371impl ZipImpl for FallbackImpl {
372 fn create_output(&self, predicate: &BooleanArray) -> Result<ArrayRef, ArrowError> {
373 zip_impl(predicate, &self.truthy, true, &self.falsy, true)
374 }
375}
376
377struct PrimitiveScalarImpl<T: ArrowPrimitiveType> {
378 data_type: DataType,
379 truthy: Option<T::Native>,
380 falsy: Option<T::Native>,
381}
382
383impl<T: ArrowPrimitiveType> Debug for PrimitiveScalarImpl<T> {
384 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
385 f.debug_struct("PrimitiveScalarImpl")
386 .field("data_type", &self.data_type)
387 .field("truthy", &self.truthy)
388 .field("falsy", &self.falsy)
389 .finish()
390 }
391}
392
393impl<T: ArrowPrimitiveType> PrimitiveScalarImpl<T> {
394 fn new(truthy: &dyn Array, falsy: &dyn Array) -> Self {
395 Self {
396 data_type: truthy.data_type().clone(),
397 truthy: Self::get_value_from_scalar(truthy),
398 falsy: Self::get_value_from_scalar(falsy),
399 }
400 }
401
402 fn get_value_from_scalar(scalar: &dyn Array) -> Option<T::Native> {
403 if scalar.is_null(0) {
404 None
405 } else {
406 let value = scalar.as_primitive::<T>().value(0);
407
408 Some(value)
409 }
410 }
411
412 fn get_scalar_and_null_buffer_for_single_non_nullable(
416 predicate: BooleanBuffer,
417 value: T::Native,
418 ) -> (Vec<T::Native>, Option<NullBuffer>) {
419 let result_len = predicate.len();
420 let nulls = NullBuffer::new(predicate);
421 let scalars = vec![value; result_len];
422
423 (scalars, Some(nulls))
424 }
425}
426
427impl<T: ArrowPrimitiveType> ZipImpl for PrimitiveScalarImpl<T> {
428 fn create_output(&self, predicate: &BooleanArray) -> Result<ArrayRef, ArrowError> {
429 let result_len = predicate.len();
430 let predicate = maybe_prep_null_mask_filter(predicate);
432
433 let (scalars, nulls): (Vec<T::Native>, Option<NullBuffer>) = match (self.truthy, self.falsy)
434 {
435 (Some(truthy_val), Some(falsy_val)) => {
436 let scalars: Vec<T::Native> = predicate
437 .iter()
438 .map(|b| if b { truthy_val } else { falsy_val })
439 .collect();
440
441 (scalars, None)
442 }
443 (Some(truthy_val), None) => {
444 Self::get_scalar_and_null_buffer_for_single_non_nullable(predicate, truthy_val)
448 }
449 (None, Some(falsy_val)) => {
450 let predicate = predicate.not();
455
456 Self::get_scalar_and_null_buffer_for_single_non_nullable(predicate, falsy_val)
457 }
458 (None, None) => {
459 let nulls = NullBuffer::new_null(result_len);
461 let scalars = vec![T::default_value(); result_len];
462
463 (scalars, Some(nulls))
464 }
465 };
466
467 let scalars = ScalarBuffer::<T::Native>::from(scalars);
468 let output = PrimitiveArray::<T>::try_new(scalars, nulls)?;
469
470 let output = output.with_data_type(self.data_type.clone());
472
473 Ok(Arc::new(output))
474 }
475}
476
477#[derive(PartialEq, Hash)]
478struct BytesScalarImpl<T: ByteArrayType> {
479 truthy: Option<Vec<u8>>,
480 falsy: Option<Vec<u8>>,
481 phantom: PhantomData<T>,
482}
483
484impl<T: ByteArrayType> Debug for BytesScalarImpl<T> {
485 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
486 f.debug_struct("BytesScalarImpl")
487 .field("truthy", &self.truthy)
488 .field("falsy", &self.falsy)
489 .finish()
490 }
491}
492
493impl<T: ByteArrayType> BytesScalarImpl<T> {
494 fn new(truthy_value: &dyn Array, falsy_value: &dyn Array) -> Self {
495 Self {
496 truthy: Self::get_value_from_scalar(truthy_value),
497 falsy: Self::get_value_from_scalar(falsy_value),
498 phantom: PhantomData,
499 }
500 }
501
502 fn get_value_from_scalar(scalar: &dyn Array) -> Option<Vec<u8>> {
503 if scalar.is_null(0) {
504 None
505 } else {
506 let bytes: &[u8] = scalar.as_bytes::<T>().value(0).as_ref();
507
508 Some(bytes.to_vec())
509 }
510 }
511
512 #[expect(clippy::type_complexity)]
516 fn get_scalar_and_null_buffer_for_single_non_nullable(
517 predicate: BooleanBuffer,
518 value: &[u8],
519 ) -> Result<(Buffer, OffsetBuffer<T::Offset>, Option<NullBuffer>), ArrowError> {
520 let value_length = value.len();
521
522 let number_of_true = predicate.count_set_bits();
523
524 if number_of_true == 0 {
526 let nulls = NullBuffer::new_null(predicate.len());
528
529 return Ok((
530 Buffer::from(&[]),
532 OffsetBuffer::<T::Offset>::new_zeroed(predicate.len()),
534 Some(nulls),
535 ));
536 }
537
538 let offsets = OffsetBuffer::<T::Offset>::from_lengths(
539 predicate.iter().map(|b| if b { value_length } else { 0 }),
540 );
541
542 let mut bytes = MutableBuffer::with_capacity(0);
543 bytes
544 .try_repeat_slice_n_times(value, number_of_true)
545 .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
546
547 let bytes = Buffer::from(bytes);
548
549 let nulls = NullBuffer::new(predicate);
552
553 Ok((bytes, offsets, Some(nulls)))
554 }
555
556 fn get_bytes_and_offset_for_all_same_value(
559 number_of_values: usize,
560 value: &[u8],
561 ) -> Result<(Buffer, OffsetBuffer<T::Offset>), ArrowError> {
562 let value_length = value.len();
563
564 let offsets =
565 OffsetBuffer::<T::Offset>::from_repeated_length(value_length, number_of_values);
566
567 let mut bytes = MutableBuffer::with_capacity(0);
568 bytes
569 .try_repeat_slice_n_times(value, number_of_values)
570 .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
571 let bytes = Buffer::from(bytes);
572
573 Ok((bytes, offsets))
574 }
575
576 fn create_output_on_non_nulls(
577 predicate: &BooleanBuffer,
578 truthy_val: &[u8],
579 falsy_val: &[u8],
580 ) -> Result<(Buffer, OffsetBuffer<<T as ByteArrayType>::Offset>), ArrowError> {
581 let true_count = predicate.count_set_bits();
582
583 match true_count {
584 0 => {
585 return Self::get_bytes_and_offset_for_all_same_value(predicate.len(), falsy_val);
587 }
588 n if n == predicate.len() => {
589 return Self::get_bytes_and_offset_for_all_same_value(predicate.len(), truthy_val);
591 }
592
593 _ => {
594 }
596 }
597
598 let total_number_of_bytes =
599 true_count * truthy_val.len() + (predicate.len() - true_count) * falsy_val.len();
600 let mut mutable = MutableBuffer::with_capacity(total_number_of_bytes);
601 let mut offset_buffer_builder = OffsetBufferBuilder::<T::Offset>::new(predicate.len());
602
603 let mut filled = 0;
605
606 let truthy_len = truthy_val.len();
607 let falsy_len = falsy_val.len();
608
609 SlicesIterator::from(predicate).try_for_each(|(start, end)| -> Result<(), ArrowError> {
610 if start > filled {
612 let false_repeat_count = start - filled;
613 mutable
615 .try_repeat_slice_n_times(falsy_val, false_repeat_count)
616 .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
617
618 for _ in 0..false_repeat_count {
619 offset_buffer_builder.push_length(falsy_len)
620 }
621 }
622
623 let true_repeat_count = end - start;
624 mutable
626 .try_repeat_slice_n_times(truthy_val, true_repeat_count)
627 .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
628
629 for _ in 0..true_repeat_count {
630 offset_buffer_builder.push_length(truthy_len)
631 }
632 filled = end;
633 Ok(())
634 })?;
635 if filled < predicate.len() {
637 let false_repeat_count = predicate.len() - filled;
638 mutable
640 .try_repeat_slice_n_times(falsy_val, false_repeat_count)
641 .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
642
643 for _ in 0..false_repeat_count {
644 offset_buffer_builder.push_length(falsy_len)
645 }
646 }
647
648 Ok((mutable.into(), offset_buffer_builder.finish()))
649 }
650}
651
652impl<T: ByteArrayType> ZipImpl for BytesScalarImpl<T> {
653 fn create_output(&self, predicate: &BooleanArray) -> Result<ArrayRef, ArrowError> {
654 let result_len = predicate.len();
655 let predicate = maybe_prep_null_mask_filter(predicate);
657
658 let (bytes, offsets, nulls): (Buffer, OffsetBuffer<T::Offset>, Option<NullBuffer>) =
659 match (self.truthy.as_deref(), self.falsy.as_deref()) {
660 (Some(truthy_val), Some(falsy_val)) => {
661 let (bytes, offsets) =
662 Self::create_output_on_non_nulls(&predicate, truthy_val, falsy_val)?;
663
664 (bytes, offsets, None)
665 }
666 (Some(truthy_val), None) => {
667 Self::get_scalar_and_null_buffer_for_single_non_nullable(predicate, truthy_val)?
668 }
669 (None, Some(falsy_val)) => {
670 let predicate = predicate.not();
675 Self::get_scalar_and_null_buffer_for_single_non_nullable(predicate, falsy_val)?
676 }
677 (None, None) => {
678 let nulls = NullBuffer::new_null(result_len);
680
681 (
682 Buffer::from(&[]),
684 OffsetBuffer::<T::Offset>::new_zeroed(predicate.len()),
686 Some(nulls),
687 )
688 }
689 };
690
691 let output = unsafe {
692 GenericByteArray::<T>::new_unchecked(offsets, bytes, nulls)
695 };
696
697 Ok(Arc::new(output))
698 }
699}
700
701fn maybe_prep_null_mask_filter(predicate: &BooleanArray) -> BooleanBuffer {
702 if predicate.null_count() == 0 {
704 predicate.values().clone()
705 } else {
706 let cleaned = prep_null_mask_filter(predicate);
707 let (boolean_buffer, _) = cleaned.into_parts();
708 boolean_buffer
709 }
710}
711
712struct ByteViewScalarImpl<T: ByteViewType> {
713 truthy_view: Option<u128>,
714 truthy_buffers: Arc<[Buffer]>,
715 falsy_view: Option<u128>,
716 falsy_buffers: Arc<[Buffer]>,
717 phantom: PhantomData<T>,
718}
719
720static EMPTY_ARC: OnceLock<Arc<[Buffer]>> = OnceLock::new();
721fn empty_arc_buffers() -> Arc<[Buffer]> {
722 Arc::clone(EMPTY_ARC.get_or_init(|| Arc::new([])))
723}
724
725impl<T: ByteViewType> ByteViewScalarImpl<T> {
726 fn new(truthy: &dyn Array, falsy: &dyn Array) -> Self {
727 let (truthy_view, truthy_buffers) = Self::get_value_from_scalar(truthy);
728 let (falsy_view, falsy_buffers) = Self::get_value_from_scalar(falsy);
729 Self {
730 truthy_view,
731 truthy_buffers,
732 falsy_view,
733 falsy_buffers,
734 phantom: PhantomData,
735 }
736 }
737
738 fn get_value_from_scalar(scalar: &dyn Array) -> (Option<u128>, Arc<[Buffer]>) {
739 if scalar.is_null(0) {
740 (None, empty_arc_buffers())
741 } else {
742 let (views, buffers, _) = scalar.as_byte_view::<T>().clone().into_parts();
743 (views.first().copied(), buffers)
744 }
745 }
746
747 fn get_views_for_single_non_nullable(
748 predicate: BooleanBuffer,
749 value: u128,
750 buffers: Arc<[Buffer]>,
751 ) -> (ScalarBuffer<u128>, Arc<[Buffer]>, Option<NullBuffer>) {
752 let number_of_true = predicate.count_set_bits();
753 let number_of_values = predicate.len();
754
755 if number_of_true == 0 {
757 return (
759 vec![0; number_of_values].into(),
760 empty_arc_buffers(),
761 Some(NullBuffer::new_null(number_of_values)),
762 );
763 }
764 let bytes = vec![value; number_of_values];
765
766 let nulls = NullBuffer::new(predicate);
769 (bytes.into(), buffers, Some(nulls))
770 }
771
772 #[expect(clippy::type_complexity)]
773 fn get_views_for_non_nullable(
774 predicate: BooleanBuffer,
775 result_len: usize,
776 truthy_view: u128,
777 truthy_buffers: Arc<[Buffer]>,
778 falsy_view: u128,
779 falsy_buffers: Arc<[Buffer]>,
780 ) -> Result<(ScalarBuffer<u128>, Arc<[Buffer]>, Option<NullBuffer>), ArrowError> {
781 let true_count = predicate.count_set_bits();
782 match true_count {
783 0 => {
784 Ok((vec![falsy_view; result_len].into(), falsy_buffers, None))
786 }
787 n if n == predicate.len() => {
788 Ok((vec![truthy_view; result_len].into(), truthy_buffers, None))
790 }
791 _ => {
792 let true_count = predicate.count_set_bits();
793 let mut buffers: Vec<Buffer> = truthy_buffers.to_vec();
794
795 let view_falsy = if falsy_buffers.is_empty() {
799 falsy_view
800 } else {
801 let byte_view_falsy = ByteView::from(falsy_view);
802 let new_index_falsy_buffers =
803 buffers.len() as u32 + byte_view_falsy.buffer_index;
804 buffers.extend(falsy_buffers.iter().cloned());
805 let byte_view_falsy =
806 byte_view_falsy.with_buffer_index(new_index_falsy_buffers);
807 byte_view_falsy.as_u128()
808 };
809
810 let total_number_of_bytes = true_count * 16 + (predicate.len() - true_count) * 16;
811 let mut mutable = MutableBuffer::new(total_number_of_bytes);
812 let mut filled = 0;
813
814 SlicesIterator::from(&predicate).try_for_each(
815 |(start, end)| -> Result<(), ArrowError> {
816 if start > filled {
817 let false_repeat_count = start - filled;
818 mutable
819 .try_repeat_slice_n_times(
820 view_falsy.to_byte_slice(),
821 false_repeat_count,
822 )
823 .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
824 }
825 let true_repeat_count = end - start;
826 mutable
827 .try_repeat_slice_n_times(
828 truthy_view.to_byte_slice(),
829 true_repeat_count,
830 )
831 .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
832 filled = end;
833 Ok(())
834 },
835 )?;
836
837 if filled < predicate.len() {
838 let false_repeat_count = predicate.len() - filled;
839 mutable
840 .try_repeat_slice_n_times(view_falsy.to_byte_slice(), false_repeat_count)
841 .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
842 }
843
844 let bytes = Buffer::from(mutable);
845 Ok((bytes.into(), buffers.into(), None))
846 }
847 }
848 }
849}
850
851impl<T: ByteViewType> Debug for ByteViewScalarImpl<T> {
852 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
853 f.debug_struct("ByteViewScalarImpl")
854 .field("truthy", &self.truthy_view)
855 .field("falsy", &self.falsy_view)
856 .finish()
857 }
858}
859
860impl<T: ByteViewType> ZipImpl for ByteViewScalarImpl<T> {
861 fn create_output(&self, predicate: &BooleanArray) -> Result<ArrayRef, ArrowError> {
862 let result_len = predicate.len();
863 let predicate = maybe_prep_null_mask_filter(predicate);
865
866 let (views, buffers, nulls) = match (self.truthy_view, self.falsy_view) {
867 (Some(truthy), Some(falsy)) => Self::get_views_for_non_nullable(
868 predicate,
869 result_len,
870 truthy,
871 Arc::clone(&self.truthy_buffers),
872 falsy,
873 Arc::clone(&self.falsy_buffers),
874 )?,
875 (Some(truthy), None) => Self::get_views_for_single_non_nullable(
876 predicate,
877 truthy,
878 Arc::clone(&self.truthy_buffers),
879 ),
880 (None, Some(falsy)) => {
881 let predicate = predicate.not();
882 Self::get_views_for_single_non_nullable(
883 predicate,
884 falsy,
885 Arc::clone(&self.falsy_buffers),
886 )
887 }
888 (None, None) => {
889 (
891 vec![0; result_len].into(),
892 empty_arc_buffers(),
893 Some(NullBuffer::new_null(result_len)),
894 )
895 }
896 };
897
898 let result = unsafe { GenericByteViewArray::<T>::new_unchecked(views, buffers, nulls) };
899 Ok(Arc::new(result))
900 }
901}
902
903#[cfg(test)]
904mod test {
905 use super::*;
906 use arrow_array::types::Int32Type;
907
908 #[test]
909 fn test_count_true_runs() {
910 let assert_runs = |values: &[bool], expected| {
911 let mask: BooleanBuffer = values.iter().copied().collect();
912 assert_eq!(count_true_runs(&mask), expected, "mask: {values:?}");
913 };
914
915 assert_runs(&[], 0);
916 assert_runs(&[false, false, false], 0);
917 assert_runs(&[true, true, true], 1);
918 assert_runs(&[true, false, true, true, false, true], 3);
919
920 let mut values = vec![false; 130];
922 values[0] = true;
923 values[63..66].fill(true);
924 values[128..].fill(true);
925 assert_runs(&values, 3);
926
927 let mut offset_values = vec![false; 135];
929 offset_values[3..133].copy_from_slice(&values);
930 let offset_mask: BooleanBuffer = offset_values.into_iter().collect();
931 assert_eq!(count_true_runs(&offset_mask.slice(3, 130)), 3);
932 }
933
934 #[test]
935 fn test_should_use_interleave() {
936 let short: BooleanBuffer = (0..64).map(|i| i % 2 == 0).collect();
937 assert!(!should_use_interleave(&short));
938
939 let fragmented: BooleanBuffer = (0..8192).map(|i| i % 2 == 0).collect();
940 assert!(should_use_interleave(&fragmented));
941
942 let long_runs: BooleanBuffer = (0..8192).map(|i| i < 4096).collect();
943 assert!(!should_use_interleave(&long_runs));
944
945 let sparse: BooleanBuffer = (0..8192).map(|i| i % 10 == 0).collect();
946 assert!(!should_use_interleave(&sparse));
947
948 let dense: BooleanBuffer = (0..8192).map(|i| i % 10 != 0).collect();
949 assert!(!should_use_interleave(&dense));
950
951 let fragmented_head: BooleanBuffer = (0..8192).map(|i| i < 256 && i % 2 == 0).collect();
952 assert!(!should_use_interleave(&fragmented_head));
953
954 let fragmented_edges: BooleanBuffer = (0..8192)
955 .map(|i| !(256..7936).contains(&i) && i % 2 == 0)
956 .collect();
957 assert!(!should_use_interleave(&fragmented_edges));
958
959 let offset: BooleanBuffer = (0..8195).map(|i| i >= 3 && i % 2 == 1).collect();
961 assert!(should_use_interleave(&offset.slice(3, 8192)));
962 }
963
964 #[test]
965 fn test_interleave_arrays() {
966 let mask = BooleanArray::from(vec![Some(true), None, Some(true), Some(false)]);
967 let mask = maybe_prep_null_mask_filter(&mask);
968 let truthy = Int32Array::from(vec![Some(1), None, Some(3), Some(4)]).to_data();
969 let falsy = Int32Array::from(vec![Some(10), Some(20), None, Some(40)]).to_data();
970 let expected = Int32Array::from(vec![Some(1), Some(20), Some(3), Some(40)]);
971
972 let actual = interleave_arrays(&mask, &truthy, &falsy).unwrap();
973 assert_eq!(actual.as_primitive::<Int32Type>(), &expected);
974 }
975
976 #[test]
977 fn test_zip_fragmented_array_mask() {
978 let mask: BooleanArray = (0..8192)
979 .map(|i| match i % 3 {
980 0 => Some(true),
981 1 => Some(false),
982 _ => None,
983 })
984 .collect();
985 let truthy: Int32Array = (0..8192).map(|i| (i % 7 != 0).then_some(i)).collect();
986 let falsy: Int32Array = (0..8192).map(|i| (i % 11 != 0).then_some(-i)).collect();
987 let expected: Int32Array = (0..8192)
988 .map(|i| {
989 let array = if i % 3 == 0 { &truthy } else { &falsy };
990 array.is_valid(i).then(|| array.value(i))
991 })
992 .collect();
993
994 let actual = zip(&mask, &truthy, &falsy).unwrap();
995 assert_eq!(actual.as_primitive::<Int32Type>(), &expected);
996 }
997
998 #[test]
999 fn test_zip_kernel_one() {
1000 let a = Int32Array::from(vec![Some(5), None, Some(7), None, Some(1)]);
1001 let b = Int32Array::from(vec![None, Some(3), Some(6), Some(7), Some(3)]);
1002 let mask = BooleanArray::from(vec![true, true, false, false, true]);
1003 let out = zip(&mask, &a, &b).unwrap();
1004 let actual = out.as_any().downcast_ref::<Int32Array>().unwrap();
1005 let expected = Int32Array::from(vec![Some(5), None, Some(6), Some(7), Some(1)]);
1006 assert_eq!(actual, &expected);
1007 }
1008
1009 #[test]
1010 fn test_zip_kernel_two() {
1011 let a = Int32Array::from(vec![Some(5), None, Some(7), None, Some(1)]);
1012 let b = Int32Array::from(vec![None, Some(3), Some(6), Some(7), Some(3)]);
1013 let mask = BooleanArray::from(vec![false, false, true, true, false]);
1014 let out = zip(&mask, &a, &b).unwrap();
1015 let actual = out.as_any().downcast_ref::<Int32Array>().unwrap();
1016 let expected = Int32Array::from(vec![None, Some(3), Some(7), None, Some(3)]);
1017 assert_eq!(actual, &expected);
1018 }
1019
1020 #[test]
1021 fn test_zip_kernel_scalar_falsy_1() {
1022 let a = Int32Array::from(vec![Some(5), None, Some(7), None, Some(1)]);
1023
1024 let fallback = Scalar::new(Int32Array::from_value(42, 1));
1025
1026 let mask = BooleanArray::from(vec![true, true, false, false, true]);
1027 let out = zip(&mask, &a, &fallback).unwrap();
1028 let actual = out.as_any().downcast_ref::<Int32Array>().unwrap();
1029 let expected = Int32Array::from(vec![Some(5), None, Some(42), Some(42), Some(1)]);
1030 assert_eq!(actual, &expected);
1031 }
1032
1033 #[test]
1034 fn test_zip_kernel_scalar_falsy_2() {
1035 let a = Int32Array::from(vec![Some(5), None, Some(7), None, Some(1)]);
1036
1037 let fallback = Scalar::new(Int32Array::from_value(42, 1));
1038
1039 let mask = BooleanArray::from(vec![false, false, true, true, false]);
1040 let out = zip(&mask, &a, &fallback).unwrap();
1041 let actual = out.as_any().downcast_ref::<Int32Array>().unwrap();
1042 let expected = Int32Array::from(vec![Some(42), Some(42), Some(7), None, Some(42)]);
1043 assert_eq!(actual, &expected);
1044 }
1045
1046 #[test]
1047 fn test_zip_kernel_scalar_truthy_1() {
1048 let a = Int32Array::from(vec![Some(5), None, Some(7), None, Some(1)]);
1049
1050 let fallback = Scalar::new(Int32Array::from_value(42, 1));
1051
1052 let mask = BooleanArray::from(vec![true, true, false, false, true]);
1053 let out = zip(&mask, &fallback, &a).unwrap();
1054 let actual = out.as_any().downcast_ref::<Int32Array>().unwrap();
1055 let expected = Int32Array::from(vec![Some(42), Some(42), Some(7), None, Some(42)]);
1056 assert_eq!(actual, &expected);
1057 }
1058
1059 #[test]
1060 fn test_zip_kernel_scalar_truthy_2() {
1061 let a = Int32Array::from(vec![Some(5), None, Some(7), None, Some(1)]);
1062
1063 let fallback = Scalar::new(Int32Array::from_value(42, 1));
1064
1065 let mask = BooleanArray::from(vec![false, false, true, true, false]);
1066 let out = zip(&mask, &fallback, &a).unwrap();
1067 let actual = out.as_any().downcast_ref::<Int32Array>().unwrap();
1068 let expected = Int32Array::from(vec![Some(5), None, Some(42), Some(42), Some(1)]);
1069 assert_eq!(actual, &expected);
1070 }
1071
1072 #[test]
1073 fn test_zip_kernel_scalar_both_mask_ends_with_true() {
1074 let scalar_truthy = Scalar::new(Int32Array::from_value(42, 1));
1075 let scalar_falsy = Scalar::new(Int32Array::from_value(123, 1));
1076
1077 let mask = BooleanArray::from(vec![true, true, false, false, true]);
1078 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1079 let actual = out.as_any().downcast_ref::<Int32Array>().unwrap();
1080 let expected = Int32Array::from(vec![Some(42), Some(42), Some(123), Some(123), Some(42)]);
1081 assert_eq!(actual, &expected);
1082 }
1083
1084 #[test]
1085 fn test_zip_kernel_scalar_both_mask_ends_with_false() {
1086 let scalar_truthy = Scalar::new(Int32Array::from_value(42, 1));
1087 let scalar_falsy = Scalar::new(Int32Array::from_value(123, 1));
1088
1089 let mask = BooleanArray::from(vec![true, true, false, true, false, false]);
1090 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1091 let actual = out.as_any().downcast_ref::<Int32Array>().unwrap();
1092 let expected = Int32Array::from(vec![
1093 Some(42),
1094 Some(42),
1095 Some(123),
1096 Some(42),
1097 Some(123),
1098 Some(123),
1099 ]);
1100 assert_eq!(actual, &expected);
1101 }
1102
1103 #[test]
1104 fn test_zip_kernel_primitive_scalar_none_1() {
1105 let scalar_truthy = Scalar::new(Int32Array::from_value(42, 1));
1106 let scalar_falsy = Scalar::new(Int32Array::new_null(1));
1107
1108 let mask = BooleanArray::from(vec![true, true, false, false, true]);
1109 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1110 let actual = out.as_any().downcast_ref::<Int32Array>().unwrap();
1111 let expected = Int32Array::from(vec![Some(42), Some(42), None, None, Some(42)]);
1112 assert_eq!(actual, &expected);
1113 }
1114
1115 #[test]
1116 fn test_zip_kernel_primitive_scalar_none_2() {
1117 let scalar_truthy = Scalar::new(Int32Array::from_value(42, 1));
1118 let scalar_falsy = Scalar::new(Int32Array::new_null(1));
1119
1120 let mask = BooleanArray::from(vec![false, false, true, true, false]);
1121 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1122 let actual = out.as_any().downcast_ref::<Int32Array>().unwrap();
1123 let expected = Int32Array::from(vec![None, None, Some(42), Some(42), None]);
1124 assert_eq!(actual, &expected);
1125 }
1126
1127 #[test]
1128 fn test_zip_kernel_primitive_scalar_both_null() {
1129 let scalar_truthy = Scalar::new(Int32Array::new_null(1));
1130 let scalar_falsy = Scalar::new(Int32Array::new_null(1));
1131
1132 let mask = BooleanArray::from(vec![false, false, true, true, false]);
1133 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1134 let actual = out.as_any().downcast_ref::<Int32Array>().unwrap();
1135 let expected = Int32Array::from(vec![None, None, None, None, None]);
1136 assert_eq!(actual, &expected);
1137 }
1138
1139 #[test]
1140 fn test_zip_primitive_array_with_nulls_is_mask_should_be_treated_as_false() {
1141 let truthy = Int32Array::from_iter_values(vec![1, 2, 3, 4, 5, 6]);
1142 let falsy = Int32Array::from_iter_values(vec![7, 8, 9, 10, 11, 12]);
1143
1144 let mask = {
1145 let booleans = BooleanBuffer::from(vec![true, true, false, true, false, false]);
1146 let nulls = NullBuffer::from(vec![
1147 true, true, true,
1148 false, true, true,
1150 ]);
1151 BooleanArray::new(booleans, Some(nulls))
1152 };
1153 let out = zip(&mask, &truthy, &falsy).unwrap();
1154 let actual = out.as_any().downcast_ref::<Int32Array>().unwrap();
1155 let expected = Int32Array::from(vec![
1156 Some(1),
1157 Some(2),
1158 Some(9),
1159 Some(10), Some(11),
1161 Some(12),
1162 ]);
1163 assert_eq!(actual, &expected);
1164 }
1165
1166 #[test]
1167 fn test_zip_kernel_primitive_scalar_with_boolean_array_mask_with_nulls_should_be_treated_as_false()
1168 {
1169 let scalar_truthy = Scalar::new(Int32Array::from_value(42, 1));
1170 let scalar_falsy = Scalar::new(Int32Array::from_value(123, 1));
1171
1172 let mask = {
1173 let booleans = BooleanBuffer::from(vec![true, true, false, true, false, false]);
1174 let nulls = NullBuffer::from(vec![
1175 true, true, true,
1176 false, true, true,
1178 ]);
1179 BooleanArray::new(booleans, Some(nulls))
1180 };
1181 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1182 let actual = out.as_any().downcast_ref::<Int32Array>().unwrap();
1183 let expected = Int32Array::from(vec![
1184 Some(42),
1185 Some(42),
1186 Some(123),
1187 Some(123), Some(123),
1189 Some(123),
1190 ]);
1191 assert_eq!(actual, &expected);
1192 }
1193
1194 #[test]
1195 fn test_zip_string_array_with_nulls_is_mask_should_be_treated_as_false() {
1196 let truthy = StringArray::from_iter_values(vec!["1", "2", "3", "4", "5", "6"]);
1197 let falsy = StringArray::from_iter_values(vec!["7", "8", "9", "10", "11", "12"]);
1198
1199 let mask = {
1200 let booleans = BooleanBuffer::from(vec![true, true, false, true, false, false]);
1201 let nulls = NullBuffer::from(vec![
1202 true, true, true,
1203 false, true, true,
1205 ]);
1206 BooleanArray::new(booleans, Some(nulls))
1207 };
1208 let out = zip(&mask, &truthy, &falsy).unwrap();
1209 let actual = out.as_string::<i32>();
1210 let expected = StringArray::from_iter_values(vec![
1211 "1", "2", "9", "10", "11", "12",
1213 ]);
1214 assert_eq!(actual, &expected);
1215 }
1216
1217 #[test]
1218 fn test_zip_kernel_large_string_scalar_with_boolean_array_mask_with_nulls_should_be_treated_as_false()
1219 {
1220 let scalar_truthy = Scalar::new(LargeStringArray::from_iter_values(["test"]));
1221 let scalar_falsy = Scalar::new(LargeStringArray::from_iter_values(["something else"]));
1222
1223 let mask = {
1224 let booleans = BooleanBuffer::from(vec![true, true, false, true, false, false]);
1225 let nulls = NullBuffer::from(vec![
1226 true, true, true,
1227 false, true, true,
1229 ]);
1230 BooleanArray::new(booleans, Some(nulls))
1231 };
1232 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1233 let actual = out.as_any().downcast_ref::<LargeStringArray>().unwrap();
1234 let expected = LargeStringArray::from_iter(vec![
1235 Some("test"),
1236 Some("test"),
1237 Some("something else"),
1238 Some("something else"), Some("something else"),
1240 Some("something else"),
1241 ]);
1242 assert_eq!(actual, &expected);
1243 }
1244
1245 #[test]
1246 fn test_zip_kernel_bytes_scalar_none_1() {
1247 let scalar_truthy = Scalar::new(StringArray::from_iter_values(["hello"]));
1248 let scalar_falsy = Scalar::new(StringArray::new_null(1));
1249
1250 let mask = BooleanArray::from(vec![true, true, false, false, true]);
1251 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1252 let actual = out.as_any().downcast_ref::<StringArray>().unwrap();
1253 let expected = StringArray::from_iter(vec![
1254 Some("hello"),
1255 Some("hello"),
1256 None,
1257 None,
1258 Some("hello"),
1259 ]);
1260 assert_eq!(actual, &expected);
1261 }
1262
1263 #[test]
1264 fn test_zip_kernel_bytes_scalar_none_2() {
1265 let scalar_truthy = Scalar::new(StringArray::new_null(1));
1266 let scalar_falsy = Scalar::new(StringArray::from_iter_values(["hello"]));
1267
1268 let mask = BooleanArray::from(vec![true, true, false, false, true]);
1269 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1270 let actual = out.as_any().downcast_ref::<StringArray>().unwrap();
1271 let expected = StringArray::from_iter(vec![None, None, Some("hello"), Some("hello"), None]);
1272 assert_eq!(actual, &expected);
1273 }
1274
1275 #[test]
1276 fn test_zip_kernel_bytes_scalar_both() {
1277 let scalar_truthy = Scalar::new(StringArray::from_iter_values(["test"]));
1278 let scalar_falsy = Scalar::new(StringArray::from_iter_values(["something else"]));
1279
1280 let mask = BooleanArray::from(vec![true, true, false, true, false, false]);
1282 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1283 let actual = out.as_any().downcast_ref::<StringArray>().unwrap();
1284 let expected = StringArray::from_iter(vec![
1285 Some("test"),
1286 Some("test"),
1287 Some("something else"),
1288 Some("test"),
1289 Some("something else"),
1290 Some("something else"),
1291 ]);
1292 assert_eq!(actual, &expected);
1293 }
1294
1295 #[test]
1296 fn test_zip_scalar_bytes_only_taking_one_side() {
1297 let mask_len = 5;
1298 let all_true_mask = BooleanArray::from(vec![true; mask_len]);
1299 let all_false_mask = BooleanArray::from(vec![false; mask_len]);
1300
1301 let null_scalar = Scalar::new(StringArray::new_null(1));
1302 let non_null_scalar_1 = Scalar::new(StringArray::from_iter_values(["test"]));
1303 let non_null_scalar_2 = Scalar::new(StringArray::from_iter_values(["something else"]));
1304
1305 {
1306 let out = zip(&all_true_mask, &null_scalar, &non_null_scalar_1).unwrap();
1309 let actual = out.as_string::<i32>();
1310 let expected = StringArray::from_iter(std::iter::repeat_n(None::<&str>, mask_len));
1311 assert_eq!(actual, &expected);
1312 }
1313
1314 {
1315 let out = zip(&all_false_mask, &null_scalar, &non_null_scalar_1).unwrap();
1318 let actual = out.as_string::<i32>();
1319 let expected = StringArray::from_iter(std::iter::repeat_n(Some("test"), mask_len));
1320 assert_eq!(actual, &expected);
1321 }
1322
1323 {
1324 let out = zip(&all_true_mask, &non_null_scalar_1, &null_scalar).unwrap();
1327 let actual = out.as_string::<i32>();
1328 let expected = StringArray::from_iter(std::iter::repeat_n(Some("test"), mask_len));
1329 assert_eq!(actual, &expected);
1330 }
1331
1332 {
1333 let out = zip(&all_false_mask, &non_null_scalar_1, &null_scalar).unwrap();
1336 let actual = out.as_string::<i32>();
1337 let expected = StringArray::from_iter(std::iter::repeat_n(None::<&str>, mask_len));
1338 assert_eq!(actual, &expected);
1339 }
1340
1341 {
1342 let out = zip(&all_true_mask, &non_null_scalar_1, &non_null_scalar_2).unwrap();
1345 let actual = out.as_string::<i32>();
1346 let expected = StringArray::from_iter(std::iter::repeat_n(Some("test"), mask_len));
1347 assert_eq!(actual, &expected);
1348 }
1349
1350 {
1351 let out = zip(&all_false_mask, &non_null_scalar_1, &non_null_scalar_2).unwrap();
1354 let actual = out.as_string::<i32>();
1355 let expected =
1356 StringArray::from_iter(std::iter::repeat_n(Some("something else"), mask_len));
1357 assert_eq!(actual, &expected);
1358 }
1359
1360 {
1361 let mask = BooleanArray::from(vec![true, false, true, false, true]);
1364 let out = zip(&mask, &null_scalar, &null_scalar).unwrap();
1365 let actual = out.as_string::<i32>();
1366 let expected = StringArray::from_iter(std::iter::repeat_n(None::<&str>, mask_len));
1367 assert_eq!(actual, &expected);
1368 }
1369 }
1370
1371 #[test]
1372 fn test_scalar_zipper() {
1373 let scalar_truthy = Scalar::new(Int32Array::from_value(42, 1));
1374 let scalar_falsy = Scalar::new(Int32Array::from_value(123, 1));
1375
1376 let mask = BooleanArray::from(vec![false, false, true, true, false]);
1377
1378 let scalar_zipper = ScalarZipper::try_new(&scalar_truthy, &scalar_falsy).unwrap();
1379 let out = scalar_zipper.zip(&mask).unwrap();
1380 let actual = out.as_primitive::<Int32Type>();
1381 let expected = Int32Array::from(vec![Some(123), Some(123), Some(42), Some(42), Some(123)]);
1382 assert_eq!(actual, &expected);
1383
1384 let mask = BooleanArray::from(vec![true, false, true]);
1386 let out = scalar_zipper.zip(&mask).unwrap();
1387 let actual = out.as_primitive::<Int32Type>();
1388 let expected = Int32Array::from(vec![Some(42), Some(123), Some(42)]);
1389 assert_eq!(actual, &expected);
1390 }
1391
1392 #[test]
1393 fn test_zip_kernel_scalar_strings() {
1394 let scalar_truthy = Scalar::new(StringArray::from(vec!["hello"]));
1395 let scalar_falsy = Scalar::new(StringArray::from(vec!["world"]));
1396
1397 let mask = BooleanArray::from(vec![true, false, true, false, true]);
1398 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1399 let actual = out.as_string::<i32>();
1400 let expected = StringArray::from(vec![
1401 Some("hello"),
1402 Some("world"),
1403 Some("hello"),
1404 Some("world"),
1405 Some("hello"),
1406 ]);
1407 assert_eq!(actual, &expected);
1408 }
1409
1410 #[test]
1411 fn test_zip_kernel_scalar_binary() {
1412 let truthy_bytes: &[u8] = b"\xFF\xFE\xFD";
1413 let falsy_bytes: &[u8] = b"world";
1414 let scalar_truthy = Scalar::new(BinaryArray::from_iter_values(
1415 vec![truthy_bytes],
1417 ));
1418 let scalar_falsy = Scalar::new(BinaryArray::from_iter_values(vec![falsy_bytes]));
1419
1420 let mask = BooleanArray::from(vec![true, false, true, false, true]);
1421 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1422 let actual = out.as_binary::<i32>();
1423 let expected = BinaryArray::from(vec![
1424 Some(truthy_bytes),
1425 Some(falsy_bytes),
1426 Some(truthy_bytes),
1427 Some(falsy_bytes),
1428 Some(truthy_bytes),
1429 ]);
1430 assert_eq!(actual, &expected);
1431 }
1432
1433 #[test]
1434 fn test_zip_kernel_scalar_large_binary() {
1435 let truthy_bytes: &[u8] = b"hey";
1436 let falsy_bytes: &[u8] = b"world";
1437 let scalar_truthy = Scalar::new(LargeBinaryArray::from_iter_values(vec![truthy_bytes]));
1438 let scalar_falsy = Scalar::new(LargeBinaryArray::from_iter_values(vec![falsy_bytes]));
1439
1440 let mask = BooleanArray::from(vec![true, false, true, false, true]);
1441 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1442 let actual = out.as_binary::<i64>();
1443 let expected = LargeBinaryArray::from(vec![
1444 Some(truthy_bytes),
1445 Some(falsy_bytes),
1446 Some(truthy_bytes),
1447 Some(falsy_bytes),
1448 Some(truthy_bytes),
1449 ]);
1450 assert_eq!(actual, &expected);
1451 }
1452
1453 #[test]
1455 fn test_zip_decimal_with_custom_precision_and_scale() {
1456 let arr = Decimal128Array::from_iter_values([12345, 456, 7890, -123223423432432])
1457 .with_precision_and_scale(20, 2)
1458 .unwrap();
1459
1460 let arr: ArrayRef = Arc::new(arr);
1461
1462 let scalar_1 = Scalar::new(arr.slice(0, 1));
1463 let scalar_2 = Scalar::new(arr.slice(1, 1));
1464 let null_scalar = Scalar::new(new_null_array(arr.data_type(), 1));
1465 let array_1: ArrayRef = arr.slice(0, 2);
1466 let array_2: ArrayRef = arr.slice(2, 2);
1467
1468 test_zip_output_data_types_for_input(scalar_1, scalar_2, null_scalar, array_1, array_2);
1469 }
1470
1471 #[test]
1473 fn test_zip_timestamp_with_timezone() {
1474 let arr = TimestampSecondArray::from(vec![0, 1000, 2000, 4000])
1475 .with_timezone("+01:00".to_string());
1476
1477 let arr: ArrayRef = Arc::new(arr);
1478
1479 let scalar_1 = Scalar::new(arr.slice(0, 1));
1480 let scalar_2 = Scalar::new(arr.slice(1, 1));
1481 let null_scalar = Scalar::new(new_null_array(arr.data_type(), 1));
1482 let array_1: ArrayRef = arr.slice(0, 2);
1483 let array_2: ArrayRef = arr.slice(2, 2);
1484
1485 test_zip_output_data_types_for_input(scalar_1, scalar_2, null_scalar, array_1, array_2);
1486 }
1487
1488 fn test_zip_output_data_types_for_input(
1489 scalar_1: Scalar<ArrayRef>,
1490 scalar_2: Scalar<ArrayRef>,
1491 null_scalar: Scalar<ArrayRef>,
1492 array_1: ArrayRef,
1493 array_2: ArrayRef,
1494 ) {
1495 test_zip_output_data_type(&scalar_1, &scalar_2, 10);
1497
1498 test_zip_output_data_type(&null_scalar, &scalar_1, 10);
1500 test_zip_output_data_type(&scalar_1, &null_scalar, 10);
1501
1502 test_zip_output_data_type(&array_1.as_ref(), &scalar_1, array_1.len());
1504 test_zip_output_data_type(&scalar_1, &array_1.as_ref(), array_1.len());
1505
1506 test_zip_output_data_type(&array_1.as_ref(), &null_scalar, array_1.len());
1508
1509 test_zip_output_data_type(&null_scalar, &array_1.as_ref(), array_1.len());
1510
1511 test_zip_output_data_type(&array_1.as_ref(), &array_2.as_ref(), array_1.len());
1513 }
1514
1515 fn test_zip_output_data_type(truthy: &dyn Datum, falsy: &dyn Datum, mask_length: usize) {
1516 let expected_data_type = truthy.get().0.data_type().clone();
1517 assert_eq!(&expected_data_type, falsy.get().0.data_type());
1518
1519 let mask_all_true = BooleanArray::from(vec![true; mask_length]);
1521 let mask_all_false = BooleanArray::from(vec![false; mask_length]);
1522 let mask_some_true_and_false =
1523 BooleanArray::from((0..mask_length).map(|i| i % 2 == 0).collect::<Vec<bool>>());
1524
1525 for mask in [&mask_all_true, &mask_all_false, &mask_some_true_and_false] {
1526 let out = zip(mask, truthy, falsy).unwrap();
1527 assert_eq!(out.data_type(), &expected_data_type);
1528 }
1529 }
1530
1531 #[test]
1532 fn zip_scalar_fallback_impl() {
1533 let truthy_list_item_scalar = Some(vec![Some(1), None, Some(3)]);
1534 let truthy_list_array_scalar =
1535 Scalar::new(ListArray::from_iter_primitive::<Int32Type, _, _>(vec![
1536 truthy_list_item_scalar.clone(),
1537 ]));
1538 let falsy_list_item_scalar = Some(vec![None, Some(2), Some(4)]);
1539 let falsy_list_array_scalar =
1540 Scalar::new(ListArray::from_iter_primitive::<Int32Type, _, _>(vec![
1541 falsy_list_item_scalar.clone(),
1542 ]));
1543 let mask = BooleanArray::from(vec![true, false, true, false, false, true, false]);
1544 let out = zip(&mask, &truthy_list_array_scalar, &falsy_list_array_scalar).unwrap();
1545 let actual = out.as_list::<i32>();
1546
1547 let expected = ListArray::from_iter_primitive::<Int32Type, _, _>(vec![
1548 truthy_list_item_scalar.clone(),
1549 falsy_list_item_scalar.clone(),
1550 truthy_list_item_scalar.clone(),
1551 falsy_list_item_scalar.clone(),
1552 falsy_list_item_scalar.clone(),
1553 truthy_list_item_scalar.clone(),
1554 falsy_list_item_scalar.clone(),
1555 ]);
1556 assert_eq!(actual, &expected);
1557 }
1558
1559 #[test]
1560 fn test_zip_kernel_scalar_strings_array_view() {
1561 let scalar_truthy = Scalar::new(StringViewArray::from(vec!["hello"]));
1562 let scalar_falsy = Scalar::new(StringViewArray::from(vec!["world"]));
1563
1564 let mask = BooleanArray::from(vec![true, false, true, false]);
1565 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1566 let actual = out.as_string_view();
1567 let expected = StringViewArray::from(vec![
1568 Some("hello"),
1569 Some("world"),
1570 Some("hello"),
1571 Some("world"),
1572 ]);
1573 assert_eq!(actual, &expected);
1574 }
1575
1576 #[test]
1577 fn test_zip_kernel_scalar_binary_array_view() {
1578 let scalar_truthy = Scalar::new(BinaryViewArray::from_iter_values(vec![b"hello"]));
1579 let scalar_falsy = Scalar::new(BinaryViewArray::from_iter_values(vec![b"world"]));
1580
1581 let mask = BooleanArray::from(vec![true, false]);
1582 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1583 let actual = out.as_byte_view();
1584 let expected = BinaryViewArray::from_iter_values(vec![b"hello", b"world"]);
1585 assert_eq!(actual, &expected);
1586 }
1587
1588 #[test]
1589 fn test_zip_kernel_scalar_strings_array_view_with_nulls() {
1590 let scalar_truthy = Scalar::new(StringViewArray::from_iter_values(["hello"]));
1591 let scalar_falsy = Scalar::new(StringViewArray::new_null(1));
1592
1593 let mask = BooleanArray::from(vec![true, true, false, false, true]);
1594 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1595 let actual = out.as_any().downcast_ref::<StringViewArray>().unwrap();
1596 let expected = StringViewArray::from_iter(vec![
1597 Some("hello"),
1598 Some("hello"),
1599 None,
1600 None,
1601 Some("hello"),
1602 ]);
1603 assert_eq!(actual, &expected);
1604 }
1605
1606 #[test]
1607 fn test_zip_kernel_scalar_strings_array_view_all_true_null() {
1608 let scalar_truthy = Scalar::new(StringViewArray::new_null(1));
1609 let scalar_falsy = Scalar::new(StringViewArray::new_null(1));
1610 let mask = BooleanArray::from(vec![true, true]);
1611 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1612 let actual = out.as_any().downcast_ref::<StringViewArray>().unwrap();
1613 let expected = StringViewArray::from_iter(vec![None::<String>, None]);
1614 assert_eq!(actual, &expected);
1615 }
1616
1617 #[test]
1618 fn test_zip_kernel_scalar_strings_array_view_all_false_null() {
1619 let scalar_truthy = Scalar::new(StringViewArray::new_null(1));
1620 let scalar_falsy = Scalar::new(StringViewArray::new_null(1));
1621 let mask = BooleanArray::from(vec![false, false]);
1622 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1623 let actual = out.as_any().downcast_ref::<StringViewArray>().unwrap();
1624 let expected = StringViewArray::from_iter(vec![None::<String>, None]);
1625 assert_eq!(actual, &expected);
1626 }
1627
1628 #[test]
1629 fn test_zip_kernel_scalar_string_array_view_all_true() {
1630 let scalar_truthy = Scalar::new(StringViewArray::from(vec!["hello"]));
1631 let scalar_falsy = Scalar::new(StringViewArray::from(vec!["world"]));
1632
1633 let mask = BooleanArray::from(vec![true, true]);
1634 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1635 let actual = out.as_string_view();
1636 let expected = StringViewArray::from(vec![Some("hello"), Some("hello")]);
1637 assert_eq!(actual, &expected);
1638 }
1639
1640 #[test]
1641 fn test_zip_kernel_scalar_string_array_view_all_false() {
1642 let scalar_truthy = Scalar::new(StringViewArray::from(vec!["hello"]));
1643 let scalar_falsy = Scalar::new(StringViewArray::from(vec!["world"]));
1644
1645 let mask = BooleanArray::from(vec![false, false]);
1646 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1647 let actual = out.as_string_view();
1648 let expected = StringViewArray::from(vec![Some("world"), Some("world")]);
1649 assert_eq!(actual, &expected);
1650 }
1651
1652 #[test]
1653 fn test_zip_kernel_scalar_strings_large_strings() {
1654 let scalar_truthy = Scalar::new(StringViewArray::from(vec!["longer than 12 bytes"]));
1655 let scalar_falsy = Scalar::new(StringViewArray::from(vec!["another longer than 12 bytes"]));
1656
1657 let mask = BooleanArray::from(vec![true, false]);
1658 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1659 let actual = out.as_string_view();
1660 let expected = StringViewArray::from(vec![
1661 Some("longer than 12 bytes"),
1662 Some("another longer than 12 bytes"),
1663 ]);
1664 assert_eq!(actual, &expected);
1665 }
1666
1667 #[test]
1668 fn test_zip_kernel_scalar_strings_array_view_large_short_strings() {
1669 let scalar_truthy = Scalar::new(StringViewArray::from(vec!["hello"]));
1670 let scalar_falsy = Scalar::new(StringViewArray::from(vec!["longer than 12 bytes"]));
1671
1672 let mask = BooleanArray::from(vec![true, false, true, false]);
1673 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1674 let actual = out.as_string_view();
1675 let expected = StringViewArray::from(vec![
1676 Some("hello"),
1677 Some("longer than 12 bytes"),
1678 Some("hello"),
1679 Some("longer than 12 bytes"),
1680 ]);
1681 assert_eq!(actual, &expected);
1682 }
1683 #[test]
1684 fn test_zip_kernel_scalar_strings_array_view_large_all_true() {
1685 let scalar_truthy = Scalar::new(StringViewArray::from(vec!["longer than 12 bytes"]));
1686 let scalar_falsy = Scalar::new(StringViewArray::from(vec!["another longer than 12 bytes"]));
1687
1688 let mask = BooleanArray::from(vec![true, true]);
1689 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1690 let actual = out.as_string_view();
1691 let expected = StringViewArray::from(vec![
1692 Some("longer than 12 bytes"),
1693 Some("longer than 12 bytes"),
1694 ]);
1695 assert_eq!(actual, &expected);
1696 }
1697
1698 #[test]
1699 fn test_zip_kernel_scalar_strings_array_view_large_all_false() {
1700 let scalar_truthy = Scalar::new(StringViewArray::from(vec!["longer than 12 bytes"]));
1701 let scalar_falsy = Scalar::new(StringViewArray::from(vec!["another longer than 12 bytes"]));
1702
1703 let mask = BooleanArray::from(vec![false, false]);
1704 let out = zip(&mask, &scalar_truthy, &scalar_falsy).unwrap();
1705 let actual = out.as_string_view();
1706 let expected = StringViewArray::from(vec![
1707 Some("another longer than 12 bytes"),
1708 Some("another longer than 12 bytes"),
1709 ]);
1710 assert_eq!(actual, &expected);
1711 }
1712}