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