1use arrow_array::*;
26use arrow_buffer::buffer::{bitwise_bin_op_helper, 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(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}