• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vortex-data / vortex / 16935267080

13 Aug 2025 11:00AM UTC coverage: 24.312% (-63.3%) from 87.658%
16935267080

Pull #4226

github

web-flow
Merge 81b48c7fb into baa6ea202
Pull Request #4226: Support converting TimestampTZ to and from duckdb

0 of 2 new or added lines in 1 file covered. (0.0%)

20666 existing lines in 469 files now uncovered.

8726 of 35892 relevant lines covered (24.31%)

147.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/vortex-array/src/compute/fill_null.rs
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3

4
use std::sync::LazyLock;
5

6
use arcref::ArcRef;
7
use vortex_dtype::DType;
8
use vortex_error::{VortexError, VortexResult, vortex_bail, vortex_err};
9
use vortex_scalar::Scalar;
10

11
use crate::compute::{ComputeFn, ComputeFnVTable, InvocationArgs, Kernel, Output, cast};
12
use crate::vtable::VTable;
13
use crate::{Array, ArrayRef, IntoArray};
14

UNCOV
15
static FILL_NULL_FN: LazyLock<ComputeFn> = LazyLock::new(|| {
×
UNCOV
16
    let compute = ComputeFn::new("fill_null".into(), ArcRef::new_ref(&FillNull));
×
UNCOV
17
    for kernel in inventory::iter::<FillNullKernelRef> {
×
UNCOV
18
        compute.register_kernel(kernel.0.clone());
×
UNCOV
19
    }
×
UNCOV
20
    compute
×
UNCOV
21
});
×
22

UNCOV
23
pub fn fill_null(array: &dyn Array, fill_value: &Scalar) -> VortexResult<ArrayRef> {
×
UNCOV
24
    FILL_NULL_FN
×
UNCOV
25
        .invoke(&InvocationArgs {
×
UNCOV
26
            inputs: &[array.into(), fill_value.into()],
×
UNCOV
27
            options: &(),
×
UNCOV
28
        })?
×
UNCOV
29
        .unwrap_array()
×
UNCOV
30
}
×
31

32
pub trait FillNullKernel: VTable {
33
    fn fill_null(&self, array: &Self::Array, fill_value: &Scalar) -> VortexResult<ArrayRef>;
34
}
35

36
pub struct FillNullKernelRef(ArcRef<dyn Kernel>);
37
inventory::collect!(FillNullKernelRef);
38

39
#[derive(Debug)]
40
pub struct FillNullKernelAdapter<V: VTable>(pub V);
41

42
impl<V: VTable + FillNullKernel> FillNullKernelAdapter<V> {
43
    pub const fn lift(&'static self) -> FillNullKernelRef {
×
44
        FillNullKernelRef(ArcRef::new_ref(self))
×
45
    }
×
46
}
47

48
impl<V: VTable + FillNullKernel> Kernel for FillNullKernelAdapter<V> {
UNCOV
49
    fn invoke(&self, args: &InvocationArgs) -> VortexResult<Option<Output>> {
×
UNCOV
50
        let inputs = FillNullArgs::try_from(args)?;
×
UNCOV
51
        let Some(array) = inputs.array.as_opt::<V>() else {
×
UNCOV
52
            return Ok(None);
×
53
        };
54
        Ok(Some(
UNCOV
55
            V::fill_null(&self.0, array, inputs.fill_value)?.into(),
×
56
        ))
UNCOV
57
    }
×
58
}
59

60
struct FillNull;
61

62
impl ComputeFnVTable for FillNull {
UNCOV
63
    fn invoke(
×
UNCOV
64
        &self,
×
UNCOV
65
        args: &InvocationArgs,
×
UNCOV
66
        kernels: &[ArcRef<dyn Kernel>],
×
UNCOV
67
    ) -> VortexResult<Output> {
×
UNCOV
68
        let FillNullArgs { array, fill_value } = FillNullArgs::try_from(args)?;
×
69

UNCOV
70
        if !array.dtype().is_nullable() {
×
UNCOV
71
            return Ok(array.to_array().into());
×
UNCOV
72
        }
×
73

UNCOV
74
        if array.all_valid()? {
×
UNCOV
75
            return Ok(cast(array, fill_value.dtype())?.into());
×
UNCOV
76
        }
×
77

UNCOV
78
        if fill_value.is_null() {
×
79
            vortex_bail!("Cannot fill_null with a null value")
×
UNCOV
80
        }
×
81

UNCOV
82
        for kernel in kernels {
×
UNCOV
83
            if let Some(output) = kernel.invoke(args)? {
×
UNCOV
84
                return Ok(output);
×
UNCOV
85
            }
×
86
        }
87
        if let Some(output) = array.invoke(&FILL_NULL_FN, args)? {
×
88
            return Ok(output);
×
89
        }
×
90

91
        log::debug!("FillNullFn not implemented for {}", array.encoding_id());
×
92
        if !array.is_canonical() {
×
93
            let canonical_arr = array.to_canonical()?.into_array();
×
94
            return Ok(fill_null(canonical_arr.as_ref(), fill_value)?.into());
×
95
        }
×
96

97
        vortex_bail!("fill null not implemented for DType {}", array.dtype())
×
UNCOV
98
    }
×
99

UNCOV
100
    fn return_dtype(&self, args: &InvocationArgs) -> VortexResult<DType> {
×
UNCOV
101
        let FillNullArgs { array, fill_value } = FillNullArgs::try_from(args)?;
×
UNCOV
102
        if !array.dtype().eq_ignore_nullability(fill_value.dtype()) {
×
103
            vortex_bail!("FillNull value must match array type (ignoring nullability)");
×
UNCOV
104
        }
×
UNCOV
105
        Ok(fill_value.dtype().clone())
×
UNCOV
106
    }
×
107

UNCOV
108
    fn return_len(&self, args: &InvocationArgs) -> VortexResult<usize> {
×
UNCOV
109
        let FillNullArgs { array, .. } = FillNullArgs::try_from(args)?;
×
UNCOV
110
        Ok(array.len())
×
UNCOV
111
    }
×
112

UNCOV
113
    fn is_elementwise(&self) -> bool {
×
UNCOV
114
        true
×
UNCOV
115
    }
×
116
}
117

118
struct FillNullArgs<'a> {
119
    array: &'a dyn Array,
120
    fill_value: &'a Scalar,
121
}
122

123
impl<'a> TryFrom<&InvocationArgs<'a>> for FillNullArgs<'a> {
124
    type Error = VortexError;
125

UNCOV
126
    fn try_from(value: &InvocationArgs<'a>) -> Result<Self, Self::Error> {
×
UNCOV
127
        if value.inputs.len() != 2 {
×
128
            vortex_bail!("FillNull requires 2 arguments");
×
UNCOV
129
        }
×
130

UNCOV
131
        let array = value.inputs[0]
×
UNCOV
132
            .array()
×
UNCOV
133
            .ok_or_else(|| vortex_err!("FillNull requires an array"))?;
×
UNCOV
134
        let fill_value = value.inputs[1]
×
UNCOV
135
            .scalar()
×
UNCOV
136
            .ok_or_else(|| vortex_err!("FillNull requires a scalar"))?;
×
137

UNCOV
138
        Ok(FillNullArgs { array, fill_value })
×
UNCOV
139
    }
×
140
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc