Returns a new array with the same values and the validity bit to false where the corresponding element of `right` is true. This can be used to implement SQL `NULLIF` # Example ``` # use arrow_array::{Int32Array, BooleanArray}; # use arrow_array::cast::AsArray; # use arrow_array::types::Int32Type; # use arrow_select::nullif::nullif; // input is [null, 8, 1, 9] let a = Int32Array::from(vec![None,
(left: &dyn Array, right: &BooleanArray)
| 42 | /// assert_eq!(nulled.as_primitive(), &Int32Array::from(vec![None, None, Some(1), Some(9)])); |
| 43 | /// ``` |
| 44 | pub fn nullif(left: &dyn Array, right: &BooleanArray) -> Result<ArrayRef, ArrowError> { |
| 45 | let left_data = left.to_data(); |
| 46 | |
| 47 | if left_data.len() != right.len() { |
| 48 | return Err(ArrowError::ComputeError( |
| 49 | "Cannot perform comparison operation on arrays of different length".to_string(), |
| 50 | )); |
| 51 | } |
| 52 | let len = left_data.len(); |
| 53 | |
| 54 | if len == 0 || left_data.data_type() == &DataType::Null { |
| 55 | return Ok(make_array(left_data)); |
| 56 | } |
| 57 | |
| 58 | // left=0 (null) right=null output bitmap=null |
| 59 | // left=0 right=1 output bitmap=null |
| 60 | // left=1 (set) right=null output bitmap=set (passthrough) |
| 61 | // left=1 right=1 & comp=true output bitmap=null |
| 62 | // left=1 right=1 & comp=false output bitmap=set |
| 63 | // |
| 64 | // Thus: result = left null bitmap & (!right_values | !right_bitmap) |
| 65 | // OR left null bitmap & !(right_values & right_bitmap) |
| 66 | |
| 67 | // Compute right_values & right_bitmap |
| 68 | let right = match right.nulls() { |
| 69 | Some(nulls) => right.values() & nulls.inner(), |
| 70 | None => right.values().clone(), |
| 71 | }; |
| 72 | |
| 73 | // Compute left null bitmap & !right |
| 74 | |
| 75 | let (combined, null_count) = match left_data.nulls() { |
| 76 | Some(left) => { |
| 77 | let mut valid_count = 0; |
| 78 | let b = bitwise_bin_op_helper( |
| 79 | left.buffer(), |
| 80 | left.offset(), |
| 81 | right.inner(), |
| 82 | right.offset(), |
| 83 | len, |
| 84 | |l, r| { |
| 85 | let t = l & !r; |
| 86 | valid_count += t.count_ones() as usize; |
| 87 | t |
| 88 | }, |
| 89 | ); |
| 90 | (b, len - valid_count) |
| 91 | } |
| 92 | None => { |
| 93 | let mut null_count = 0; |
| 94 | let buffer = bitwise_unary_op_helper(right.inner(), right.offset(), len, |b| { |
| 95 | let t = !b; |
| 96 | null_count += t.count_zeros() as usize; |
| 97 | t |
| 98 | }); |
| 99 | (buffer, null_count) |
| 100 | } |
| 101 | }; |