1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
use vortex_error::VortexResult;
use vortex_scalar::Scalar;

use crate::array::{ChunkedArray, ChunkedEncoding};
use crate::compute::{fill_null, FillNullFn};
use crate::{ArrayDType, ArrayData, IntoArrayData};

impl FillNullFn<ChunkedArray> for ChunkedEncoding {
    fn fill_null(&self, array: &ChunkedArray, fill_value: Scalar) -> VortexResult<ArrayData> {
        ChunkedArray::try_new(
            array
                .chunks()
                .map(|c| fill_null(c, fill_value.clone()))
                .collect::<VortexResult<Vec<_>>>()?,
            array.dtype().as_nonnullable(),
        )
        .map(|a| a.into_array())
    }
}

#[cfg(test)]
mod tests {
    use arrow_buffer::BooleanBuffer;
    use vortex_dtype::{DType, Nullability};

    use crate::array::{BoolArray, ChunkedArray};
    use crate::compute::fill_null;
    use crate::validity::Validity;
    use crate::{ArrayDType, IntoArrayData};

    #[test]
    fn fill_null_chunks() {
        let chunked = ChunkedArray::try_new(
            vec![
                BoolArray::try_new(BooleanBuffer::new_set(5), Validity::AllInvalid)
                    .unwrap()
                    .into_array(),
                BoolArray::new(BooleanBuffer::new_set(5), Nullability::Nullable).into_array(),
            ],
            DType::Bool(Nullability::Nullable),
        )
        .unwrap();

        let filled = fill_null(chunked, false.into()).unwrap();
        assert_eq!(*filled.dtype(), DType::Bool(Nullability::NonNullable));
    }
}