1use arrow_array::*;
26use arrow_buffer::buffer::bitwise_quaternary_op_helper;
27use arrow_buffer::{BooleanBuffer, NullBuffer, buffer_bin_and_not};
28use arrow_schema::ArrowError;
29
30pub fn and_kleene(left: &BooleanArray, right: &BooleanArray) -> Result<BooleanArray, ArrowError> {
61 if left.len() != right.len() {
62 return Err(ArrowError::ComputeError(
63 "Cannot perform bitwise operation on arrays of different length".to_string(),
64 ));
65 }
66
67 let left_values = left.values();
68 let right_values = right.values();
69
70 let buffer = match (left.nulls(), right.nulls()) {
71 (None, None) => None,
72 (Some(left_null_buffer), None) => {
73 Some(BooleanBuffer::from_bitwise_binary_op(
78 left_null_buffer.buffer(),
79 left_null_buffer.offset(),
80 right_values.inner(),
81 right_values.offset(),
82 left.len(),
83 |a, b| a | !b,
84 ))
85 }
86 (None, Some(right_null_buffer)) => {
87 Some(BooleanBuffer::from_bitwise_binary_op(
89 right_null_buffer.buffer(),
90 right_null_buffer.offset(),
91 left_values.inner(),
92 left_values.offset(),
93 left.len(),
94 |a, b| a | !b,
95 ))
96 }
97 (Some(left_null_buffer), Some(right_null_buffer)) => {
98 let buffer = bitwise_quaternary_op_helper(
104 [
105 left_null_buffer.buffer(),
106 left_values.inner(),
107 right_null_buffer.buffer(),
108 right_values.inner(),
109 ],
110 [
111 left_null_buffer.offset(),
112 left_values.offset(),
113 right_null_buffer.offset(),
114 right_values.offset(),
115 ],
116 left.len(),
117 |a, b, c, d| (a | (c & !d)) & (c | (a & !b)),
118 );
119 Some(BooleanBuffer::new(buffer, 0, left.len()))
120 }
121 };
122 let nulls = buffer.map(NullBuffer::new);
123 Ok(BooleanArray::new(left_values & right_values, nulls))
124}
125
126pub fn or_kleene(left: &BooleanArray, right: &BooleanArray) -> Result<BooleanArray, ArrowError> {
157 if left.len() != right.len() {
158 return Err(ArrowError::ComputeError(
159 "Cannot perform bitwise operation on arrays of different length".to_string(),
160 ));
161 }
162
163 let left_values = left.values();
164 let right_values = right.values();
165
166 let buffer = match (left.nulls(), right.nulls()) {
167 (None, None) => None,
168 (Some(left_nulls), None) => {
169 Some(BooleanBuffer::from_bitwise_binary_op(
174 left_nulls.buffer(),
175 left_nulls.offset(),
176 right_values.inner(),
177 right_values.offset(),
178 left.len(),
179 |a, b| a | b,
180 ))
181 }
182 (None, Some(right_nulls)) => {
183 Some(BooleanBuffer::from_bitwise_binary_op(
185 right_nulls.buffer(),
186 right_nulls.offset(),
187 left_values.inner(),
188 left_values.offset(),
189 left.len(),
190 |a, b| a | b,
191 ))
192 }
193 (Some(left_nulls), Some(right_nulls)) => {
194 let buffer = bitwise_quaternary_op_helper(
200 [
201 left_nulls.buffer(),
202 left_values.inner(),
203 right_nulls.buffer(),
204 right_values.inner(),
205 ],
206 [
207 left_nulls.offset(),
208 left_values.offset(),
209 right_nulls.offset(),
210 right_values.offset(),
211 ],
212 left.len(),
213 |a, b, c, d| (a | (c & d)) & (c | (a & b)),
214 );
215 Some(BooleanBuffer::new(buffer, 0, left.len()))
216 }
217 };
218
219 let nulls = buffer.map(NullBuffer::new);
220 Ok(BooleanArray::new(left_values | right_values, nulls))
221}
222
223pub(crate) fn binary_boolean_kernel<F>(
225 left: &BooleanArray,
226 right: &BooleanArray,
227 op: F,
228) -> Result<BooleanArray, ArrowError>
229where
230 F: Fn(&BooleanBuffer, &BooleanBuffer) -> BooleanBuffer,
231{
232 if left.len() != right.len() {
233 return Err(ArrowError::ComputeError(
234 "Cannot perform bitwise operation on arrays of different length".to_string(),
235 ));
236 }
237
238 let nulls = NullBuffer::union(left.nulls(), right.nulls());
239 let values = op(left.values(), right.values());
240 Ok(BooleanArray::new(values, nulls))
241}
242
243pub fn and(left: &BooleanArray, right: &BooleanArray) -> Result<BooleanArray, ArrowError> {
257 binary_boolean_kernel(left, right, |a, b| a & b)
258}
259
260pub fn or(left: &BooleanArray, right: &BooleanArray) -> Result<BooleanArray, ArrowError> {
274 binary_boolean_kernel(left, right, |a, b| a | b)
275}
276
277pub fn and_not(left: &BooleanArray, right: &BooleanArray) -> Result<BooleanArray, ArrowError> {
292 binary_boolean_kernel(left, right, |a, b| {
293 let buffer = buffer_bin_and_not(a.inner(), a.offset(), b.inner(), b.offset(), a.len());
294 BooleanBuffer::new(buffer, 0, left.len())
295 })
296}
297
298pub fn not(left: &BooleanArray) -> Result<BooleanArray, ArrowError> {
311 let nulls = left.nulls().cloned();
312 let values = !left.values();
313 Ok(BooleanArray::new(values, nulls))
314}
315
316pub fn is_null(input: &dyn Array) -> Result<BooleanArray, ArrowError> {
328 let values = match input.logical_nulls() {
329 None => BooleanBuffer::new_unset(input.len()),
330 Some(nulls) => !nulls.inner(),
331 };
332
333 Ok(BooleanArray::new(values, None))
334}
335
336pub fn is_not_null(input: &dyn Array) -> Result<BooleanArray, ArrowError> {
348 let values = match input.logical_nulls() {
349 None => BooleanBuffer::new_set(input.len()),
350 Some(n) => n.inner().clone(),
351 };
352 Ok(BooleanArray::new(values, None))
353}
354
355#[cfg(test)]
356mod tests {
357 use arrow_buffer::ScalarBuffer;
358 use arrow_schema::{DataType, Field, UnionFields};
359
360 use super::*;
361 use std::sync::Arc;
362
363 #[test]
364 fn test_bool_array_and() {
365 let a = BooleanArray::from(vec![false, false, true, true]);
366 let b = BooleanArray::from(vec![false, true, false, true]);
367 let c = and(&a, &b).unwrap();
368
369 let expected = BooleanArray::from(vec![false, false, false, true]);
370
371 assert_eq!(c, expected);
372 }
373
374 #[test]
375 fn test_bool_array_or() {
376 let a = BooleanArray::from(vec![false, false, true, true]);
377 let b = BooleanArray::from(vec![false, true, false, true]);
378 let c = or(&a, &b).unwrap();
379
380 let expected = BooleanArray::from(vec![false, true, true, true]);
381
382 assert_eq!(c, expected);
383 }
384
385 #[test]
386 fn test_bool_array_and_not() {
387 let a = BooleanArray::from(vec![false, false, true, true]);
388 let b = BooleanArray::from(vec![false, true, false, true]);
389 let c = and_not(&a, &b).unwrap();
390
391 let expected = BooleanArray::from(vec![false, false, true, false]);
392
393 assert_eq!(c, expected);
394 assert_eq!(c, and(&a, ¬(&b).unwrap()).unwrap());
395 }
396
397 #[test]
398 fn test_bool_array_and_not_sliced() {
399 let a = BooleanArray::from(vec![true, false, true, false, true, false, true]);
400 let b = BooleanArray::from(vec![false, true, false, true, false, true, false]);
401 let a = a.slice(2, 3);
402 let b = b.slice(2, 3);
403 let a = a.as_any().downcast_ref::<BooleanArray>().unwrap();
404 let b = b.as_any().downcast_ref::<BooleanArray>().unwrap();
405
406 assert_eq!(and_not(a, b).unwrap(), and(a, ¬(b).unwrap()).unwrap());
407 }
408
409 #[test]
410 fn test_bool_array_and_not_sliced_different_offsets() {
411 let a = BooleanArray::from(vec![false, true, true, false, true, false, true]);
412 let b = BooleanArray::from(vec![true, false, false, true, false, true, false]);
413 let a = a.slice(1, 4);
414 let b = b.slice(2, 4);
415 let a = a.as_any().downcast_ref::<BooleanArray>().unwrap();
416 let b = b.as_any().downcast_ref::<BooleanArray>().unwrap();
417
418 assert_eq!(and_not(a, b).unwrap(), and(a, ¬(b).unwrap()).unwrap());
419 }
420
421 #[test]
422 fn test_bool_array_or_nulls() {
423 let a = BooleanArray::from(vec![
424 None,
425 None,
426 None,
427 Some(false),
428 Some(false),
429 Some(false),
430 Some(true),
431 Some(true),
432 Some(true),
433 ]);
434 let b = BooleanArray::from(vec![
435 None,
436 Some(false),
437 Some(true),
438 None,
439 Some(false),
440 Some(true),
441 None,
442 Some(false),
443 Some(true),
444 ]);
445 let c = or(&a, &b).unwrap();
446
447 let expected = BooleanArray::from(vec![
448 None,
449 None,
450 None,
451 None,
452 Some(false),
453 Some(true),
454 None,
455 Some(true),
456 Some(true),
457 ]);
458
459 assert_eq!(c, expected);
460 }
461
462 #[test]
463 fn test_boolean_array_kleene_no_remainder() {
464 let n = 1024;
465 let a = BooleanArray::from(vec![true; n]);
466 let b = BooleanArray::from(vec![None; n]);
467 let result = or_kleene(&a, &b).unwrap();
468
469 assert_eq!(result, a);
470 }
471
472 #[test]
473 fn test_bool_array_and_kleene_nulls() {
474 let a = BooleanArray::from(vec![
475 None,
476 None,
477 None,
478 Some(false),
479 Some(false),
480 Some(false),
481 Some(true),
482 Some(true),
483 Some(true),
484 ]);
485 let b = BooleanArray::from(vec![
486 None,
487 Some(false),
488 Some(true),
489 None,
490 Some(false),
491 Some(true),
492 None,
493 Some(false),
494 Some(true),
495 ]);
496 let c = and_kleene(&a, &b).unwrap();
497
498 let expected = BooleanArray::from(vec![
499 None,
500 Some(false),
501 None,
502 Some(false),
503 Some(false),
504 Some(false),
505 None,
506 Some(false),
507 Some(true),
508 ]);
509
510 assert_eq!(c, expected);
511 }
512
513 #[test]
514 fn test_bool_array_or_kleene_nulls() {
515 let a = BooleanArray::from(vec![
516 None,
517 None,
518 None,
519 Some(false),
520 Some(false),
521 Some(false),
522 Some(true),
523 Some(true),
524 Some(true),
525 ]);
526 let b = BooleanArray::from(vec![
527 None,
528 Some(false),
529 Some(true),
530 None,
531 Some(false),
532 Some(true),
533 None,
534 Some(false),
535 Some(true),
536 ]);
537 let c = or_kleene(&a, &b).unwrap();
538
539 let expected = BooleanArray::from(vec![
540 None,
541 None,
542 Some(true),
543 None,
544 Some(false),
545 Some(true),
546 Some(true),
547 Some(true),
548 Some(true),
549 ]);
550
551 assert_eq!(c, expected);
552 }
553
554 #[test]
555 fn test_bool_array_or_kleene_right_sided_nulls() {
556 let a = BooleanArray::from(vec![false, false, false, true, true, true]);
557
558 assert!(a.nulls().is_none());
560
561 let b = BooleanArray::from(vec![
562 Some(true),
563 Some(false),
564 None,
565 Some(true),
566 Some(false),
567 None,
568 ]);
569
570 assert!(b.nulls().is_some());
572
573 let c = or_kleene(&a, &b).unwrap();
574
575 let expected = BooleanArray::from(vec![
576 Some(true),
577 Some(false),
578 None,
579 Some(true),
580 Some(true),
581 Some(true),
582 ]);
583
584 assert_eq!(c, expected);
585 }
586
587 #[test]
588 fn test_bool_array_or_kleene_left_sided_nulls() {
589 let a = BooleanArray::from(vec![
590 Some(true),
591 Some(false),
592 None,
593 Some(true),
594 Some(false),
595 None,
596 ]);
597
598 assert!(a.nulls().is_some());
600
601 let b = BooleanArray::from(vec![false, false, false, true, true, true]);
602
603 assert!(b.nulls().is_none());
605
606 let c = or_kleene(&a, &b).unwrap();
607
608 let expected = BooleanArray::from(vec![
609 Some(true),
610 Some(false),
611 None,
612 Some(true),
613 Some(true),
614 Some(true),
615 ]);
616
617 assert_eq!(c, expected);
618 }
619
620 #[test]
621 fn test_bool_array_not() {
622 let a = BooleanArray::from(vec![false, true]);
623 let c = not(&a).unwrap();
624
625 let expected = BooleanArray::from(vec![true, false]);
626
627 assert_eq!(c, expected);
628 }
629
630 #[test]
631 fn test_bool_array_not_sliced() {
632 let a = BooleanArray::from(vec![None, Some(true), Some(false), None, Some(true)]);
633 let a = a.slice(1, 4);
634 let a = a.as_any().downcast_ref::<BooleanArray>().unwrap();
635 let c = not(a).unwrap();
636
637 let expected = BooleanArray::from(vec![Some(false), Some(true), None, Some(false)]);
638
639 assert_eq!(c, expected);
640 }
641
642 #[test]
643 fn test_bool_array_and_nulls() {
644 let a = BooleanArray::from(vec![
645 None,
646 None,
647 None,
648 Some(false),
649 Some(false),
650 Some(false),
651 Some(true),
652 Some(true),
653 Some(true),
654 ]);
655 let b = BooleanArray::from(vec![
656 None,
657 Some(false),
658 Some(true),
659 None,
660 Some(false),
661 Some(true),
662 None,
663 Some(false),
664 Some(true),
665 ]);
666 let c = and(&a, &b).unwrap();
667
668 let expected = BooleanArray::from(vec![
669 None,
670 None,
671 None,
672 None,
673 Some(false),
674 Some(false),
675 None,
676 Some(false),
677 Some(true),
678 ]);
679
680 assert_eq!(c, expected);
681 }
682
683 #[test]
684 fn test_bool_array_and_sliced_same_offset() {
685 let a = BooleanArray::from(vec![
686 false, false, false, false, false, false, false, false, false, false, true, true,
687 ]);
688 let b = BooleanArray::from(vec![
689 false, false, false, false, false, false, false, false, false, true, false, true,
690 ]);
691
692 let a = a.slice(8, 4);
693 let a = a.as_any().downcast_ref::<BooleanArray>().unwrap();
694 let b = b.slice(8, 4);
695 let b = b.as_any().downcast_ref::<BooleanArray>().unwrap();
696
697 let c = and(a, b).unwrap();
698
699 let expected = BooleanArray::from(vec![false, false, false, true]);
700
701 assert_eq!(expected, c);
702 }
703
704 #[test]
705 fn test_bool_array_and_sliced_same_offset_mod8() {
706 let a = BooleanArray::from(vec![
707 false, false, true, true, false, false, false, false, false, false, false, false,
708 ]);
709 let b = BooleanArray::from(vec![
710 false, false, false, false, false, false, false, false, false, true, false, true,
711 ]);
712
713 let a = a.slice(0, 4);
714 let a = a.as_any().downcast_ref::<BooleanArray>().unwrap();
715 let b = b.slice(8, 4);
716 let b = b.as_any().downcast_ref::<BooleanArray>().unwrap();
717
718 let c = and(a, b).unwrap();
719
720 let expected = BooleanArray::from(vec![false, false, false, true]);
721
722 assert_eq!(expected, c);
723 }
724
725 #[test]
726 fn test_bool_array_and_sliced_offset1() {
727 let a = BooleanArray::from(vec![
728 false, false, false, false, false, false, false, false, false, false, true, true,
729 ]);
730 let b = BooleanArray::from(vec![false, true, false, true]);
731
732 let a = a.slice(8, 4);
733 let a = a.as_any().downcast_ref::<BooleanArray>().unwrap();
734
735 let c = and(a, &b).unwrap();
736
737 let expected = BooleanArray::from(vec![false, false, false, true]);
738
739 assert_eq!(expected, c);
740 }
741
742 #[test]
743 fn test_bool_array_and_sliced_offset2() {
744 let a = BooleanArray::from(vec![false, false, true, true]);
745 let b = BooleanArray::from(vec![
746 false, false, false, false, false, false, false, false, false, true, false, true,
747 ]);
748
749 let b = b.slice(8, 4);
750 let b = b.as_any().downcast_ref::<BooleanArray>().unwrap();
751
752 let c = and(&a, b).unwrap();
753
754 let expected = BooleanArray::from(vec![false, false, false, true]);
755
756 assert_eq!(expected, c);
757 }
758
759 #[test]
760 fn test_bool_array_and_nulls_offset() {
761 let a = BooleanArray::from(vec![None, Some(false), Some(true), None, Some(true)]);
762 let a = a.slice(1, 4);
763 let a = a.as_any().downcast_ref::<BooleanArray>().unwrap();
764
765 let b = BooleanArray::from(vec![
766 None,
767 None,
768 Some(true),
769 Some(false),
770 Some(true),
771 Some(true),
772 ]);
773
774 let b = b.slice(2, 4);
775 let b = b.as_any().downcast_ref::<BooleanArray>().unwrap();
776
777 let c = and(a, b).unwrap();
778
779 let expected = BooleanArray::from(vec![Some(false), Some(false), None, Some(true)]);
780
781 assert_eq!(expected, c);
782 }
783
784 #[test]
785 fn test_nonnull_array_is_null() {
786 let a: ArrayRef = Arc::new(Int32Array::from(vec![1, 2, 3, 4]));
787
788 let res = is_null(a.as_ref()).unwrap();
789
790 let expected = BooleanArray::from(vec![false, false, false, false]);
791
792 assert_eq!(expected, res);
793 assert!(res.nulls().is_none());
794 }
795
796 #[test]
797 fn test_nonnull_array_with_offset_is_null() {
798 let a = Int32Array::from(vec![1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1]);
799 let a = a.slice(8, 4);
800
801 let res = is_null(&a).unwrap();
802
803 let expected = BooleanArray::from(vec![false, false, false, false]);
804
805 assert_eq!(expected, res);
806 assert!(res.nulls().is_none());
807 }
808
809 #[test]
810 fn test_nonnull_array_is_not_null() {
811 let a = Int32Array::from(vec![1, 2, 3, 4]);
812
813 let res = is_not_null(&a).unwrap();
814
815 let expected = BooleanArray::from(vec![true, true, true, true]);
816
817 assert_eq!(expected, res);
818 assert!(res.nulls().is_none());
819 }
820
821 #[test]
822 fn test_nonnull_array_with_offset_is_not_null() {
823 let a = Int32Array::from(vec![1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1]);
824 let a = a.slice(8, 4);
825
826 let res = is_not_null(&a).unwrap();
827
828 let expected = BooleanArray::from(vec![true, true, true, true]);
829
830 assert_eq!(expected, res);
831 assert!(res.nulls().is_none());
832 }
833
834 #[test]
835 fn test_nullable_array_is_null() {
836 let a = Int32Array::from(vec![Some(1), None, Some(3), None]);
837
838 let res = is_null(&a).unwrap();
839
840 let expected = BooleanArray::from(vec![false, true, false, true]);
841
842 assert_eq!(expected, res);
843 assert!(res.nulls().is_none());
844 }
845
846 #[test]
847 fn test_nullable_array_with_offset_is_null() {
848 let a = Int32Array::from(vec![
849 None,
850 None,
851 None,
852 None,
853 None,
854 None,
855 None,
856 None,
857 Some(1),
859 None,
860 Some(2),
861 None,
862 Some(3),
863 Some(4),
864 None,
865 None,
866 ]);
867 let a = a.slice(8, 4);
868
869 let res = is_null(&a).unwrap();
870
871 let expected = BooleanArray::from(vec![false, true, false, true]);
872
873 assert_eq!(expected, res);
874 assert!(res.nulls().is_none());
875 }
876
877 #[test]
878 fn test_nullable_array_is_not_null() {
879 let a = Int32Array::from(vec![Some(1), None, Some(3), None]);
880
881 let res = is_not_null(&a).unwrap();
882
883 let expected = BooleanArray::from(vec![true, false, true, false]);
884
885 assert_eq!(expected, res);
886 assert!(res.nulls().is_none());
887 }
888
889 #[test]
890 fn test_nullable_array_with_offset_is_not_null() {
891 let a = Int32Array::from(vec![
892 None,
893 None,
894 None,
895 None,
896 None,
897 None,
898 None,
899 None,
900 Some(1),
902 None,
903 Some(2),
904 None,
905 Some(3),
906 Some(4),
907 None,
908 None,
909 ]);
910 let a = a.slice(8, 4);
911
912 let res = is_not_null(&a).unwrap();
913
914 let expected = BooleanArray::from(vec![true, false, true, false]);
915
916 assert_eq!(expected, res);
917 assert!(res.nulls().is_none());
918 }
919
920 #[test]
921 fn test_null_array_is_null() {
922 let a = NullArray::new(3);
923
924 let res = is_null(&a).unwrap();
925
926 let expected = BooleanArray::from(vec![true, true, true]);
927
928 assert_eq!(expected, res);
929 assert!(res.nulls().is_none());
930 }
931
932 #[test]
933 fn test_null_array_is_not_null() {
934 let a = NullArray::new(3);
935
936 let res = is_not_null(&a).unwrap();
937
938 let expected = BooleanArray::from(vec![false, false, false]);
939
940 assert_eq!(expected, res);
941 assert!(res.nulls().is_none());
942 }
943
944 #[test]
945 fn test_dense_union_is_null() {
946 let int_array = Int32Array::from(vec![Some(1), None]);
948 let float_array = Float64Array::from(vec![Some(3.2), None]);
949 let str_array = StringArray::from(vec![Some("a"), None]);
950 let type_ids = [0, 0, 1, 1, 2, 2].into_iter().collect::<ScalarBuffer<i8>>();
951 let offsets = [0, 1, 0, 1, 0, 1]
952 .into_iter()
953 .collect::<ScalarBuffer<i32>>();
954
955 let children = vec![
956 Arc::new(int_array) as Arc<dyn Array>,
957 Arc::new(float_array),
958 Arc::new(str_array),
959 ];
960
961 let array = UnionArray::try_new(union_fields(), type_ids, Some(offsets), children).unwrap();
962
963 let result = is_null(&array).unwrap();
964
965 let expected = &BooleanArray::from(vec![false, true, false, true, false, true]);
966 assert_eq!(expected, &result);
967 }
968
969 #[test]
970 fn test_sparse_union_is_null() {
971 let int_array = Int32Array::from(vec![Some(1), None, None, None, None, None]);
973 let float_array = Float64Array::from(vec![None, None, Some(3.2), None, None, None]);
974 let str_array = StringArray::from(vec![None, None, None, None, Some("a"), None]);
975 let type_ids = [0, 0, 1, 1, 2, 2].into_iter().collect::<ScalarBuffer<i8>>();
976
977 let children = vec![
978 Arc::new(int_array) as Arc<dyn Array>,
979 Arc::new(float_array),
980 Arc::new(str_array),
981 ];
982
983 let array = UnionArray::try_new(union_fields(), type_ids, None, children).unwrap();
984
985 let result = is_null(&array).unwrap();
986
987 let expected = &BooleanArray::from(vec![false, true, false, true, false, true]);
988 assert_eq!(expected, &result);
989 }
990
991 fn union_fields() -> UnionFields {
992 [
993 (0, Arc::new(Field::new("A", DataType::Int32, true))),
994 (1, Arc::new(Field::new("B", DataType::Float64, true))),
995 (2, Arc::new(Field::new("C", DataType::Utf8, true))),
996 ]
997 .into_iter()
998 .collect()
999 }
1000}