## Coverage Report

#### Created: 2025-08-26 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /Users/andrewlamb/Software/arrow-rs/arrow-arith/src/boolean.rs

    Line
    Count
    Source
    1
    // Licensed to the Apache Software Foundation (ASF) under one
    2
    // or more contributor license agreements.  See the NOTICE file
    3
    // distributed with this work for additional information
    4
    // regarding copyright ownership.  The ASF licenses this file
    5
    // to you under the Apache License, Version 2.0 (the
    6
    // "License"); you may not use this file except in compliance
    7
    // with the License.  You may obtain a copy of the License at
    8
    //
    9
    //   http://www.apache.org/licenses/LICENSE-2.0
    10
    //
    11
    // Unless required by applicable law or agreed to in writing,
    12
    // software distributed under the License is distributed on an
    13
    // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    14
    // KIND, either express or implied.  See the License for the
    15
    // specific language governing permissions and limitations
    16
    // under the License.
    17
    18
    //! Defines boolean kernels on Arrow `BooleanArray`'s, e.g. `AND`, `OR` and `NOT`.
    19
    //!
    20
    //! These kernels can leverage SIMD if available on your system.  Currently no runtime
    21
    //! detection is provided, you should enable the specific SIMD intrinsics using
    22
    //! `RUSTFLAGS="-C target-feature=+avx2"` for example.  See the documentation
    23
    //! [here](https://doc.rust-lang.org/stable/core/arch/) for more information.
    24
    25
    use arrow_array::*;
    26
    use arrow_buffer::buffer::{bitwise_bin_op_helper, bitwise_quaternary_op_helper};
    27
    use arrow_buffer::{buffer_bin_and_not, BooleanBuffer, NullBuffer};
    28
    use arrow_schema::ArrowError;
    29
    30
    /// Logical 'and' boolean values with Kleene logic
    31
    ///
    32
    /// # Behavior
    33
    ///
    34
    /// This function behaves as follows with nulls:
    35
    ///
    36
    /// * `true` and `null` = `null`
    37
    /// * `null` and `true` = `null`
    38
    /// * `false` and `null` = `false`
    39
    /// * `null` and `false` = `false`
    40
    /// * `null` and `null` = `null`
    41
    ///
    42
    /// In other words, in this context a null value really means \"unknown\",
    43
    /// and an unknown value 'and' false is always false.
    44
    /// For a different null behavior, see function \"and\".
    45
    ///
    46
    /// # Example
    47
    ///
    48
    /// ```rust
    49
    /// # use arrow_array::BooleanArray;
    50
    /// # use arrow_arith::boolean::and_kleene;
    51
    /// let a = BooleanArray::from(vec![Some(true), Some(false), None]);
    52
    /// let b = BooleanArray::from(vec![None, None, None]);
    53
    /// let and_ab = and_kleene(&a, &b).unwrap();
    54
    /// assert_eq!(and_ab, BooleanArray::from(vec![None, Some(false), None]));
    55
    /// ```
    56
    ///
    57
    /// # Fails
    58
    ///
    59
    /// If the operands have different lengths
    60
    pub 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
                // The right side has no null values.
    74
                // The final null bit is set only if:
    75
                // 1. left null bit is set, or
    76
                // 2. right data bit is false (because null AND false = false).
    77
                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
    0
                    |a, b| a | !b,
    84
                ))
    85
            }
    86
            (None, Some(right_null_buffer)) => {
    87
                // Same as above
    88
                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
    0
                    |a, b| a | !b,
    95
                ))
    96
            }
    97
            (Some(left_null_buffer), Some(right_null_buffer)) => {
    98
                // Follow the same logic above. Both sides have null values.
    99
                // Assume a is left null bits, b is left data bits, c is right null bits,
    100
                // d is right data bits.
    101
                // The final null bits are:
    102
                // (a | (c & !d)) & (c | (a & !b))
    103
                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
    0
                    |a, b, c, d| (a | (c & !d)) & (c | (a & !b)),
    118
                ))
    119
            }
    120
        };
    121
    0
        let nulls = buffer.map(|b| NullBuffer::new(BooleanBuffer::new(b, 0, left.len())));
    122
        Ok(BooleanArray::new(left_values & right_values, nulls))
    123
    }
    124
    125
    /// Logical 'or' boolean values with Kleene logic
    126
    ///
    127
    /// # Behavior
    128
    ///
    129
    /// This function behaves as follows with nulls:
    130
    ///
    131
    /// * `true` or `null` = `true`
    132
    /// * `null` or `true` = `true`
    133
    /// * `false` or `null` = `null`
    134
    /// * `null` or `false` = `null`
    135
    /// * `null` or `null` = `null`
    136
    ///
    137
    /// In other words, in this context a null value really means \"unknown\",
    138
    /// and an unknown value 'or' true is always true.
    139
    /// For a different null behavior, see function \"or\".
    140
    ///
    141
    /// # Example
    142
    ///
    143
    /// ```rust
    144
    /// # use arrow_array::BooleanArray;
    145
    /// # use arrow_arith::boolean::or_kleene;
    146
    /// let a = BooleanArray::from(vec![Some(true), Some(false), None]);
    147
    /// let b = BooleanArray::from(vec![None, None, None]);
    148
    /// let or_ab = or_kleene(&a, &b).unwrap();
    149
    /// assert_eq!(or_ab, BooleanArray::from(vec![Some(true), None, None]));
    150
    /// ```
    151
    ///
    152
    /// # Fails
    153
    ///
    154
    /// If the operands have different lengths
    155
    pub 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
                // The right side has no null values.
    169
                // The final null bit is set only if:
    170
                // 1. left null bit is set, or
    171
                // 2. right data bit is true (because null OR true = true).
    172
                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
    0
                    |a, b| a | b,
    179
                ))
    180
            }
    181
            (None, Some(right_nulls)) => {
    182
                // Same as above
    183
                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
    0
                    |a, b| a | b,
    190
                ))
    191
            }
    192
            (Some(left_nulls), Some(right_nulls)) => {
    193
                // Follow the same logic above. Both sides have null values.
    194
                // Assume a is left null bits, b is left data bits, c is right null bits,
    195
                // d is right data bits.
    196
                // The final null bits are:
    197
                // (a | (c & d)) & (c | (a & b))
    198
                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
    0
                    |a, b, c, d| (a | (c & d)) & (c | (a & b)),
    213
                ))
    214
            }
    215
        };
    216
    217
    0
        let nulls = buffer.map(|b| NullBuffer::new(BooleanBuffer::new(b, 0, left.len())));
    218
        Ok(BooleanArray::new(left_values | right_values, nulls))
    219
    }
    220
    221
    /// Helper function to implement binary kernels
    222
    0
    pub(crate) fn binary_boolean_kernel<F>(
    223
    0
        left: &BooleanArray,
    224
    0
        right: &BooleanArray,
    225
    0
        op: F,
    226
    0
    ) -> Result<BooleanArray, ArrowError>
    227
    0
    where
    228
    0
        F: Fn(&BooleanBuffer, &BooleanBuffer) -> BooleanBuffer,
    229
    {
    230
    0
        if left.len() != right.len() {
    231
    0
            return Err(ArrowError::ComputeError(
    232
    0
                "Cannot perform bitwise operation on arrays of different length".to_string(),
    233
    0
            ));
    234
    0
        }
    235
    236
    0
        let nulls = NullBuffer::union(left.nulls(), right.nulls());
    237
    0
        let values = op(left.values(), right.values());
    238
    0
        Ok(BooleanArray::new(values, nulls))
    239
    0
    }
    240
    241
    /// Performs `AND` operation on two arrays. If either left or right value is null then the
    242
    /// result is also null.
    243
    /// # Error
    244
    /// This function errors when the arrays have different lengths.
    245
    /// # Example
    246
    /// ```rust
    247
    /// # use arrow_array::BooleanArray;
    248
    /// # use arrow_arith::boolean::and;
    249
    /// let a = BooleanArray::from(vec![Some(false), Some(true), None]);
    250
    /// let b = BooleanArray::from(vec![Some(true), Some(true), Some(false)]);
    251
    /// let and_ab = and(&a, &b).unwrap();
    252
    /// assert_eq!(and_ab, BooleanArray::from(vec![Some(false), Some(true), None]));
    253
    /// ```
    254
    pub fn and(left: &BooleanArray, right: &BooleanArray) -> Result<BooleanArray, ArrowError> {
    255
    0
        binary_boolean_kernel(left, right, |a, b| a & b)
    256
    }
    257
    258
    /// Performs `OR` operation on two arrays. If either left or right value is null then the
    259
    /// result is also null.
    260
    /// # Error
    261
    /// This function errors when the arrays have different lengths.
    262
    /// # Example
    263
    /// ```rust
    264
    /// # use arrow_array::BooleanArray;
    265
    /// # use arrow_arith::boolean::or;
    266
    /// let a = BooleanArray::from(vec![Some(false), Some(true), None]);
    267
    /// let b = BooleanArray::from(vec![Some(true), Some(true), Some(false)]);
    268
    /// let or_ab = or(&a, &b).unwrap();
    269
    /// assert_eq!(or_ab, BooleanArray::from(vec![Some(true), Some(true), None]));
    270
    /// ```
    271
    pub fn or(left: &BooleanArray, right: &BooleanArray) -> Result<BooleanArray, ArrowError> {
    272
    0
        binary_boolean_kernel(left, right, |a, b| a | b)
    273
    }
    274
    275
    /// Performs `AND_NOT` operation on two arrays. If either left or right value is null then the
    276
    /// result is also null.
    277
    /// # Error
    278
    /// This function errors when the arrays have different lengths.
    279
    /// # Example
    280
    /// ```rust
    281
    /// # use arrow_array::BooleanArray;
    282
    /// # use arrow_arith::boolean::{and, not, and_not};
    283
    /// let a = BooleanArray::from(vec![Some(false), Some(true), None]);
    284
    /// let b = BooleanArray::from(vec![Some(true), Some(true), Some(false)]);
    285
    /// let andn_ab = and_not(&a, &b).unwrap();
    286
    /// assert_eq!(andn_ab, BooleanArray::from(vec![Some(false), Some(false), None]));
    287
    /// // It's equal to and(left, not(right))
    288
    /// assert_eq!(andn_ab, and(&a, &not(&b).unwrap()).unwrap());
    289
    pub fn and_not(left: &BooleanArray, right: &BooleanArray) -> Result<BooleanArray, ArrowError> {
    290
    0
        binary_boolean_kernel(left, right, |a, b| {
    291
    0
            let buffer = buffer_bin_and_not(a.inner(), b.offset(), b.inner(), a.offset(), a.len());
    292
    0
            BooleanBuffer::new(buffer, left.offset(), left.len())
    293
    0
        })
    294
    }
    295
    296
    /// Performs unary `NOT` operation on an arrays. If value is null then the result is also
    297
    /// null.
    298
    /// # Error
    299
    /// This function never errors. It returns an error for consistency.
    300
    /// # Example
    301
    /// ```rust
    302
    /// # use arrow_array::BooleanArray;
    303
    /// # use arrow_arith::boolean::not;
    304
    /// let a = BooleanArray::from(vec![Some(false), Some(true), None]);
    305
    /// let not_a = not(&a).unwrap();
    306
    /// assert_eq!(not_a, BooleanArray::from(vec![Some(true), Some(false), None]));
    307
    /// ```
    308
    pub 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
    314
    /// Returns a non-null [BooleanArray] with whether each value of the array is null.
    315
    /// # Error
    316
    /// This function never errors.
    317
    /// # Example
    318
    /// ```rust
    319
    /// # use arrow_array::BooleanArray;
    320
    /// # use arrow_arith::boolean::is_null;
    321
    /// let a = BooleanArray::from(vec![Some(false), Some(true), None]);
    322
    /// let a_is_null = is_null(&a).unwrap();
    323
    /// assert_eq!(a_is_null, BooleanArray::from(vec![false, false, true]));
    324
    /// ```
    325
    pub 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
    334
    /// Returns a non-null [BooleanArray] with whether each value of the array is not null.
    335
    /// # Error
    336
    /// This function never errors.
    337
    /// # Example
    338
    /// ```rust
    339
    /// # use arrow_array::BooleanArray;
    340
    /// # use arrow_arith::boolean::is_not_null;
    341
    /// let a = BooleanArray::from(vec![Some(false), Some(true), None]);
    342
    /// let a_is_not_null = is_not_null(&a).unwrap();
    343
    /// assert_eq!(a_is_not_null, BooleanArray::from(vec![true, true, false]));
    344
    /// ```
    345
    pub 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)]
    354
    mod 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, &not(&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
            // ensure null bitmap of a is absent
    533
            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
            // ensure null bitmap of b is present
    545
            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
            // ensure null bitmap of b is absent
    573
            assert!(a.nulls().is_some());
    574
    575
            let b = BooleanArray::from(vec![false, false, false, true, true, true]);
    576
    577
            // ensure null bitmap of a is present
    578
            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
                // offset 8, previous None values are skipped by the slice
    832
                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
                // offset 8, previous None values are skipped by the slice
    875
                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
            // union of [{A=1}, {A=}, {B=3.2}, {B=}, {C="a"}, {C=}]
    921
            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
            // union of [{A=1}, {A=}, {B=3.2}, {B=}, {C="a"}, {C=}]
    946
            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
    }