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(), b.offset(), b.inner(), a.offset(), a.len());
294 BooleanBuffer::new(buffer, left.offset(), 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_or_nulls() {
399 let a = BooleanArray::from(vec![
400 None,
401 None,
402 None,
403 Some(false),
404 Some(false),
405 Some(false),
406 Some(true),
407 Some(true),
408 Some(true),
409 ]);
410 let b = BooleanArray::from(vec![
411 None,
412 Some(false),
413 Some(true),
414 None,
415 Some(false),
416 Some(true),
417 None,
418 Some(false),
419 Some(true),
420 ]);
421 let c = or(&a, &b).unwrap();
422
423 let expected = BooleanArray::from(vec![
424 None,
425 None,
426 None,
427 None,
428 Some(false),
429 Some(true),
430 None,
431 Some(true),
432 Some(true),
433 ]);
434
435 assert_eq!(c, expected);
436 }
437
438 #[test]
439 fn test_boolean_array_kleene_no_remainder() {
440 let n = 1024;
441 let a = BooleanArray::from(vec![true; n]);
442 let b = BooleanArray::from(vec![None; n]);
443 let result = or_kleene(&a, &b).unwrap();
444
445 assert_eq!(result, a);
446 }
447
448 #[test]
449 fn test_bool_array_and_kleene_nulls() {
450 let a = BooleanArray::from(vec![
451 None,
452 None,
453 None,
454 Some(false),
455 Some(false),
456 Some(false),
457 Some(true),
458 Some(true),
459 Some(true),
460 ]);
461 let b = BooleanArray::from(vec![
462 None,
463 Some(false),
464 Some(true),
465 None,
466 Some(false),
467 Some(true),
468 None,
469 Some(false),
470 Some(true),
471 ]);
472 let c = and_kleene(&a, &b).unwrap();
473
474 let expected = BooleanArray::from(vec![
475 None,
476 Some(false),
477 None,
478 Some(false),
479 Some(false),
480 Some(false),
481 None,
482 Some(false),
483 Some(true),
484 ]);
485
486 assert_eq!(c, expected);
487 }
488
489 #[test]
490 fn test_bool_array_or_kleene_nulls() {
491 let a = BooleanArray::from(vec![
492 None,
493 None,
494 None,
495 Some(false),
496 Some(false),
497 Some(false),
498 Some(true),
499 Some(true),
500 Some(true),
501 ]);
502 let b = BooleanArray::from(vec![
503 None,
504 Some(false),
505 Some(true),
506 None,
507 Some(false),
508 Some(true),
509 None,
510 Some(false),
511 Some(true),
512 ]);
513 let c = or_kleene(&a, &b).unwrap();
514
515 let expected = BooleanArray::from(vec![
516 None,
517 None,
518 Some(true),
519 None,
520 Some(false),
521 Some(true),
522 Some(true),
523 Some(true),
524 Some(true),
525 ]);
526
527 assert_eq!(c, expected);
528 }
529
530 #[test]
531 fn test_bool_array_or_kleene_right_sided_nulls() {
532 let a = BooleanArray::from(vec![false, false, false, true, true, true]);
533
534 assert!(a.nulls().is_none());
536
537 let b = BooleanArray::from(vec![
538 Some(true),
539 Some(false),
540 None,
541 Some(true),
542 Some(false),
543 None,
544 ]);
545
546 assert!(b.nulls().is_some());
548
549 let c = or_kleene(&a, &b).unwrap();
550
551 let expected = BooleanArray::from(vec![
552 Some(true),
553 Some(false),
554 None,
555 Some(true),
556 Some(true),
557 Some(true),
558 ]);
559
560 assert_eq!(c, expected);
561 }
562
563 #[test]
564 fn test_bool_array_or_kleene_left_sided_nulls() {
565 let a = BooleanArray::from(vec![
566 Some(true),
567 Some(false),
568 None,
569 Some(true),
570 Some(false),
571 None,
572 ]);
573
574 assert!(a.nulls().is_some());
576
577 let b = BooleanArray::from(vec![false, false, false, true, true, true]);
578
579 assert!(b.nulls().is_none());
581
582 let c = or_kleene(&a, &b).unwrap();
583
584 let expected = BooleanArray::from(vec![
585 Some(true),
586 Some(false),
587 None,
588 Some(true),
589 Some(true),
590 Some(true),
591 ]);
592
593 assert_eq!(c, expected);
594 }
595
596 #[test]
597 fn test_bool_array_not() {
598 let a = BooleanArray::from(vec![false, true]);
599 let c = not(&a).unwrap();
600
601 let expected = BooleanArray::from(vec![true, false]);
602
603 assert_eq!(c, expected);
604 }
605
606 #[test]
607 fn test_bool_array_not_sliced() {
608 let a = BooleanArray::from(vec![None, Some(true), Some(false), None, Some(true)]);
609 let a = a.slice(1, 4);
610 let a = a.as_any().downcast_ref::<BooleanArray>().unwrap();
611 let c = not(a).unwrap();
612
613 let expected = BooleanArray::from(vec![Some(false), Some(true), None, Some(false)]);
614
615 assert_eq!(c, expected);
616 }
617
618 #[test]
619 fn test_bool_array_and_nulls() {
620 let a = BooleanArray::from(vec![
621 None,
622 None,
623 None,
624 Some(false),
625 Some(false),
626 Some(false),
627 Some(true),
628 Some(true),
629 Some(true),
630 ]);
631 let b = BooleanArray::from(vec![
632 None,
633 Some(false),
634 Some(true),
635 None,
636 Some(false),
637 Some(true),
638 None,
639 Some(false),
640 Some(true),
641 ]);
642 let c = and(&a, &b).unwrap();
643
644 let expected = BooleanArray::from(vec![
645 None,
646 None,
647 None,
648 None,
649 Some(false),
650 Some(false),
651 None,
652 Some(false),
653 Some(true),
654 ]);
655
656 assert_eq!(c, expected);
657 }
658
659 #[test]
660 fn test_bool_array_and_sliced_same_offset() {
661 let a = BooleanArray::from(vec![
662 false, false, false, false, false, false, false, false, false, false, true, true,
663 ]);
664 let b = BooleanArray::from(vec![
665 false, false, false, false, false, false, false, false, false, true, false, true,
666 ]);
667
668 let a = a.slice(8, 4);
669 let a = a.as_any().downcast_ref::<BooleanArray>().unwrap();
670 let b = b.slice(8, 4);
671 let b = b.as_any().downcast_ref::<BooleanArray>().unwrap();
672
673 let c = and(a, b).unwrap();
674
675 let expected = BooleanArray::from(vec![false, false, false, true]);
676
677 assert_eq!(expected, c);
678 }
679
680 #[test]
681 fn test_bool_array_and_sliced_same_offset_mod8() {
682 let a = BooleanArray::from(vec![
683 false, false, true, true, false, false, false, false, false, false, false, false,
684 ]);
685 let b = BooleanArray::from(vec![
686 false, false, false, false, false, false, false, false, false, true, false, true,
687 ]);
688
689 let a = a.slice(0, 4);
690 let a = a.as_any().downcast_ref::<BooleanArray>().unwrap();
691 let b = b.slice(8, 4);
692 let b = b.as_any().downcast_ref::<BooleanArray>().unwrap();
693
694 let c = and(a, b).unwrap();
695
696 let expected = BooleanArray::from(vec![false, false, false, true]);
697
698 assert_eq!(expected, c);
699 }
700
701 #[test]
702 fn test_bool_array_and_sliced_offset1() {
703 let a = BooleanArray::from(vec![
704 false, false, false, false, false, false, false, false, false, false, true, true,
705 ]);
706 let b = BooleanArray::from(vec![false, true, false, true]);
707
708 let a = a.slice(8, 4);
709 let a = a.as_any().downcast_ref::<BooleanArray>().unwrap();
710
711 let c = and(a, &b).unwrap();
712
713 let expected = BooleanArray::from(vec![false, false, false, true]);
714
715 assert_eq!(expected, c);
716 }
717
718 #[test]
719 fn test_bool_array_and_sliced_offset2() {
720 let a = BooleanArray::from(vec![false, false, true, true]);
721 let b = BooleanArray::from(vec![
722 false, false, false, false, false, false, false, false, false, true, false, true,
723 ]);
724
725 let b = b.slice(8, 4);
726 let b = b.as_any().downcast_ref::<BooleanArray>().unwrap();
727
728 let c = and(&a, b).unwrap();
729
730 let expected = BooleanArray::from(vec![false, false, false, true]);
731
732 assert_eq!(expected, c);
733 }
734
735 #[test]
736 fn test_bool_array_and_nulls_offset() {
737 let a = BooleanArray::from(vec![None, Some(false), Some(true), None, Some(true)]);
738 let a = a.slice(1, 4);
739 let a = a.as_any().downcast_ref::<BooleanArray>().unwrap();
740
741 let b = BooleanArray::from(vec![
742 None,
743 None,
744 Some(true),
745 Some(false),
746 Some(true),
747 Some(true),
748 ]);
749
750 let b = b.slice(2, 4);
751 let b = b.as_any().downcast_ref::<BooleanArray>().unwrap();
752
753 let c = and(a, b).unwrap();
754
755 let expected = BooleanArray::from(vec![Some(false), Some(false), None, Some(true)]);
756
757 assert_eq!(expected, c);
758 }
759
760 #[test]
761 fn test_nonnull_array_is_null() {
762 let a: ArrayRef = Arc::new(Int32Array::from(vec![1, 2, 3, 4]));
763
764 let res = is_null(a.as_ref()).unwrap();
765
766 let expected = BooleanArray::from(vec![false, false, false, false]);
767
768 assert_eq!(expected, res);
769 assert!(res.nulls().is_none());
770 }
771
772 #[test]
773 fn test_nonnull_array_with_offset_is_null() {
774 let a = Int32Array::from(vec![1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1]);
775 let a = a.slice(8, 4);
776
777 let res = is_null(&a).unwrap();
778
779 let expected = BooleanArray::from(vec![false, false, false, false]);
780
781 assert_eq!(expected, res);
782 assert!(res.nulls().is_none());
783 }
784
785 #[test]
786 fn test_nonnull_array_is_not_null() {
787 let a = Int32Array::from(vec![1, 2, 3, 4]);
788
789 let res = is_not_null(&a).unwrap();
790
791 let expected = BooleanArray::from(vec![true, true, true, true]);
792
793 assert_eq!(expected, res);
794 assert!(res.nulls().is_none());
795 }
796
797 #[test]
798 fn test_nonnull_array_with_offset_is_not_null() {
799 let a = Int32Array::from(vec![1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1]);
800 let a = a.slice(8, 4);
801
802 let res = is_not_null(&a).unwrap();
803
804 let expected = BooleanArray::from(vec![true, true, true, true]);
805
806 assert_eq!(expected, res);
807 assert!(res.nulls().is_none());
808 }
809
810 #[test]
811 fn test_nullable_array_is_null() {
812 let a = Int32Array::from(vec![Some(1), None, Some(3), None]);
813
814 let res = is_null(&a).unwrap();
815
816 let expected = BooleanArray::from(vec![false, true, false, true]);
817
818 assert_eq!(expected, res);
819 assert!(res.nulls().is_none());
820 }
821
822 #[test]
823 fn test_nullable_array_with_offset_is_null() {
824 let a = Int32Array::from(vec![
825 None,
826 None,
827 None,
828 None,
829 None,
830 None,
831 None,
832 None,
833 Some(1),
835 None,
836 Some(2),
837 None,
838 Some(3),
839 Some(4),
840 None,
841 None,
842 ]);
843 let a = a.slice(8, 4);
844
845 let res = is_null(&a).unwrap();
846
847 let expected = BooleanArray::from(vec![false, true, false, true]);
848
849 assert_eq!(expected, res);
850 assert!(res.nulls().is_none());
851 }
852
853 #[test]
854 fn test_nullable_array_is_not_null() {
855 let a = Int32Array::from(vec![Some(1), None, Some(3), None]);
856
857 let res = is_not_null(&a).unwrap();
858
859 let expected = BooleanArray::from(vec![true, false, true, false]);
860
861 assert_eq!(expected, res);
862 assert!(res.nulls().is_none());
863 }
864
865 #[test]
866 fn test_nullable_array_with_offset_is_not_null() {
867 let a = Int32Array::from(vec![
868 None,
869 None,
870 None,
871 None,
872 None,
873 None,
874 None,
875 None,
876 Some(1),
878 None,
879 Some(2),
880 None,
881 Some(3),
882 Some(4),
883 None,
884 None,
885 ]);
886 let a = a.slice(8, 4);
887
888 let res = is_not_null(&a).unwrap();
889
890 let expected = BooleanArray::from(vec![true, false, true, false]);
891
892 assert_eq!(expected, res);
893 assert!(res.nulls().is_none());
894 }
895
896 #[test]
897 fn test_null_array_is_null() {
898 let a = NullArray::new(3);
899
900 let res = is_null(&a).unwrap();
901
902 let expected = BooleanArray::from(vec![true, true, true]);
903
904 assert_eq!(expected, res);
905 assert!(res.nulls().is_none());
906 }
907
908 #[test]
909 fn test_null_array_is_not_null() {
910 let a = NullArray::new(3);
911
912 let res = is_not_null(&a).unwrap();
913
914 let expected = BooleanArray::from(vec![false, false, false]);
915
916 assert_eq!(expected, res);
917 assert!(res.nulls().is_none());
918 }
919
920 #[test]
921 fn test_dense_union_is_null() {
922 let int_array = Int32Array::from(vec![Some(1), None]);
924 let float_array = Float64Array::from(vec![Some(3.2), None]);
925 let str_array = StringArray::from(vec![Some("a"), None]);
926 let type_ids = [0, 0, 1, 1, 2, 2].into_iter().collect::<ScalarBuffer<i8>>();
927 let offsets = [0, 1, 0, 1, 0, 1]
928 .into_iter()
929 .collect::<ScalarBuffer<i32>>();
930
931 let children = vec![
932 Arc::new(int_array) as Arc<dyn Array>,
933 Arc::new(float_array),
934 Arc::new(str_array),
935 ];
936
937 let array = UnionArray::try_new(union_fields(), type_ids, Some(offsets), children).unwrap();
938
939 let result = is_null(&array).unwrap();
940
941 let expected = &BooleanArray::from(vec![false, true, false, true, false, true]);
942 assert_eq!(expected, &result);
943 }
944
945 #[test]
946 fn test_sparse_union_is_null() {
947 let int_array = Int32Array::from(vec![Some(1), None, None, None, None, None]);
949 let float_array = Float64Array::from(vec![None, None, Some(3.2), None, None, None]);
950 let str_array = StringArray::from(vec![None, None, None, None, Some("a"), None]);
951 let type_ids = [0, 0, 1, 1, 2, 2].into_iter().collect::<ScalarBuffer<i8>>();
952
953 let children = vec![
954 Arc::new(int_array) as Arc<dyn Array>,
955 Arc::new(float_array),
956 Arc::new(str_array),
957 ];
958
959 let array = UnionArray::try_new(union_fields(), type_ids, None, children).unwrap();
960
961 let result = is_null(&array).unwrap();
962
963 let expected = &BooleanArray::from(vec![false, true, false, true, false, true]);
964 assert_eq!(expected, &result);
965 }
966
967 fn union_fields() -> UnionFields {
968 [
969 (0, Arc::new(Field::new("A", DataType::Int32, true))),
970 (1, Arc::new(Field::new("B", DataType::Float64, true))),
971 (2, Arc::new(Field::new("C", DataType::Utf8, true))),
972 ]
973 .into_iter()
974 .collect()
975 }
976}