vortex_array/arrays/scalar_fn/vtable/
validity.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use vortex_dtype::Nullability;
5use vortex_error::VortexExpect;
6use vortex_error::VortexResult;
7use vortex_mask::Mask;
8use vortex_vector::Datum;
9use vortex_vector::ScalarOps;
10use vortex_vector::VectorOps;
11
12use crate::Array;
13use crate::LEGACY_SESSION;
14use crate::arrays::scalar_fn::array::ScalarFnArray;
15use crate::arrays::scalar_fn::vtable::ScalarFnVTable;
16use crate::executor::VectorExecutor;
17use crate::validity::Validity;
18use crate::vtable::ValidityVTable;
19
20impl ValidityVTable<ScalarFnVTable> for ScalarFnVTable {
21    fn is_valid(array: &ScalarFnArray, index: usize) -> bool {
22        array.scalar_at(index).is_valid()
23    }
24
25    fn all_valid(array: &ScalarFnArray) -> bool {
26        match array.scalar_fn.signature().is_null_sensitive() {
27            true => {
28                // If the function is null sensitive, we cannot guarantee all valid without evaluating
29                // the function
30                false
31            }
32            false => {
33                // If the function is not null sensitive, we can guarantee all valid if all children
34                // are all valid
35                array.children().iter().all(|child| child.all_valid())
36            }
37        }
38    }
39
40    fn all_invalid(array: &ScalarFnArray) -> bool {
41        match array.scalar_fn.signature().is_null_sensitive() {
42            true => {
43                // If the function is null sensitive, we cannot guarantee all invalid without evaluating
44                // the function
45                false
46            }
47            false => {
48                // If the function is not null sensitive, we can guarantee all invalid if any child
49                // is all invalid
50                array.children().iter().any(|child| child.all_invalid())
51            }
52        }
53    }
54
55    fn validity(array: &ScalarFnArray) -> VortexResult<Validity> {
56        // TODO(ngates): we should add an execute_validity function to ScalarFn.
57        //  Or have more descriptive null sensitivity metadata.
58        Ok(Validity::from_mask(
59            Self::validity_mask(array),
60            Nullability::Nullable,
61        ))
62    }
63
64    fn validity_mask(array: &ScalarFnArray) -> Mask {
65        let datum = array
66            .to_array()
67            .execute_datum(&LEGACY_SESSION)
68            .vortex_expect("Validity mask computation should be fallible");
69        match datum {
70            Datum::Scalar(s) => Mask::new(array.len, s.is_valid()),
71            Datum::Vector(v) => v.validity().clone(),
72        }
73    }
74}