vortex_array/arrays/dict/compute/
fill_null.rs1use vortex_error::VortexResult;
5use vortex_scalar::{Scalar, ScalarValue};
6
7use super::{DictArray, DictVTable};
8use crate::arrays::ConstantArray;
9use crate::compute::{FillNullKernel, FillNullKernelAdapter, Operator, compare, fill_null};
10use crate::{Array, ArrayRef, IntoArray, ToCanonical, register_kernel};
11
12impl FillNullKernel for DictVTable {
13 fn fill_null(&self, array: &DictArray, fill_value: &Scalar) -> VortexResult<ArrayRef> {
14 let found_fill_values = compare(
17 array.values(),
18 ConstantArray::new(fill_value.clone(), array.values().len()).as_ref(),
19 Operator::Eq,
20 )?
21 .to_bool();
22
23 let Some(first_fill_value) = found_fill_values.bit_buffer().set_indices().next() else {
24 return fill_null(&array.to_canonical().into_array(), fill_value);
28 };
29
30 let codes = fill_null(
32 array.codes(),
33 &Scalar::new(
34 array
35 .codes()
36 .dtype()
37 .with_nullability(fill_value.dtype().nullability()),
38 ScalarValue::from(first_fill_value),
39 ),
40 )?;
41 let values = fill_null(array.values(), fill_value)?;
43
44 unsafe { Ok(DictArray::new_unchecked(codes, values).into_array()) }
46 }
47}
48
49register_kernel!(FillNullKernelAdapter(DictVTable).lift());
50
51#[cfg(test)]
52mod tests {
53 use vortex_buffer::{BitBuffer, buffer};
54 use vortex_dtype::Nullability;
55 use vortex_error::VortexUnwrap;
56 use vortex_scalar::Scalar;
57
58 use crate::arrays::PrimitiveArray;
59 use crate::arrays::dict::DictArray;
60 use crate::compute::fill_null;
61 use crate::validity::Validity;
62 use crate::{IntoArray, ToCanonical, assert_arrays_eq};
63
64 #[test]
65 fn nullable_codes_fill_in_values() {
66 let dict = DictArray::try_new(
67 PrimitiveArray::new(
68 buffer![0u32, 1, 2],
69 Validity::from(BitBuffer::from(vec![true, false, true])),
70 )
71 .into_array(),
72 PrimitiveArray::new(buffer![10, 20, 20], Validity::AllValid).into_array(),
73 )
74 .vortex_unwrap();
75
76 let filled = fill_null(
77 dict.as_ref(),
78 &Scalar::primitive(20, Nullability::NonNullable),
79 )
80 .vortex_unwrap();
81 let filled_primitive = filled.to_primitive();
82 assert_arrays_eq!(filled_primitive, PrimitiveArray::from_iter([10, 20, 20]));
83 assert!(filled_primitive.all_valid());
84 }
85}