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