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