vortex_array/arrays/bool/compute/
fill_null.rs1use vortex_error::{VortexResult, vortex_err};
5use vortex_scalar::Scalar;
6
7use crate::arrays::{BoolArray, BoolVTable, ConstantArray};
8use crate::compute::{FillNullKernel, FillNullKernelAdapter};
9use crate::validity::Validity;
10use crate::vtable::ValidityHelper;
11use crate::{ArrayRef, IntoArray, ToCanonical, register_kernel};
12
13impl FillNullKernel for BoolVTable {
14 fn fill_null(&self, array: &BoolArray, fill_value: &Scalar) -> VortexResult<ArrayRef> {
15 let fill = fill_value
16 .as_bool()
17 .value()
18 .ok_or_else(|| vortex_err!("Fill value must be non null"))?;
19
20 Ok(match array.validity() {
21 Validity::NonNullable | Validity::AllValid => BoolArray::new(
22 array.boolean_buffer().clone(),
23 fill_value.dtype().nullability().into(),
24 )
25 .into_array(),
26 Validity::AllInvalid => {
27 ConstantArray::new(fill_value.clone(), array.len()).into_array()
28 }
29 Validity::Array(v) => {
30 let bool_buffer = if fill {
31 array.boolean_buffer() | &!v.to_bool()?.boolean_buffer()
32 } else {
33 array.boolean_buffer() & v.to_bool()?.boolean_buffer()
34 };
35 BoolArray::new(bool_buffer, fill_value.dtype().nullability().into()).into_array()
36 }
37 })
38 }
39}
40
41register_kernel!(FillNullKernelAdapter(BoolVTable).lift());
42
43#[cfg(test)]
44mod tests {
45 use arrow_buffer::BooleanBuffer;
46 use rstest::rstest;
47 use vortex_dtype::{DType, Nullability};
48
49 use crate::arrays::BoolArray;
50 use crate::canonical::ToCanonical;
51 use crate::compute::fill_null;
52 use crate::validity::Validity;
53
54 #[rstest]
55 #[case(true, vec![true, true, false, true])]
56 #[case(false, vec![true, false, false, false])]
57 fn bool_fill_null(#[case] fill_value: bool, #[case] expected: Vec<bool>) {
58 let bool_array = BoolArray::new(
59 BooleanBuffer::from_iter([true, true, false, false]),
60 Validity::from_iter([true, false, true, false]),
61 );
62 let non_null_array = fill_null(bool_array.as_ref(), &fill_value.into())
63 .unwrap()
64 .to_bool()
65 .unwrap();
66 assert_eq!(
67 non_null_array.boolean_buffer().iter().collect::<Vec<_>>(),
68 expected
69 );
70 assert_eq!(
71 non_null_array.dtype(),
72 &DType::Bool(Nullability::NonNullable)
73 );
74 }
75}