Skip to main content

vortex_array/arrays/null/compute/
cast.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use vortex_error::VortexResult;
5use vortex_error::vortex_bail;
6
7use crate::ArrayRef;
8use crate::IntoArray;
9use crate::arrays::ConstantArray;
10use crate::arrays::NullArray;
11use crate::arrays::NullVTable;
12use crate::dtype::DType;
13use crate::scalar::Scalar;
14use crate::scalar_fn::fns::cast::CastReduce;
15
16impl CastReduce for NullVTable {
17    fn cast(array: &NullArray, dtype: &DType) -> VortexResult<Option<ArrayRef>> {
18        if !dtype.is_nullable() {
19            vortex_bail!("Cannot cast Null to {}", dtype);
20        }
21        if dtype == &DType::Null {
22            return Ok(Some(array.clone().into_array()));
23        }
24
25        let scalar = Scalar::null(dtype.clone());
26        Ok(Some(ConstantArray::new(scalar, array.len()).into_array()))
27    }
28}
29
30#[cfg(test)]
31mod tests {
32    use rstest::rstest;
33
34    use crate::IntoArray;
35    use crate::arrays::NullArray;
36    use crate::builtins::ArrayBuiltins;
37    use crate::compute::conformance::cast::test_cast_conformance;
38    use crate::dtype::DType;
39    use crate::dtype::Nullability;
40    use crate::dtype::PType;
41
42    #[test]
43    fn test_cast_null_to_null() {
44        let null_array = NullArray::new(5);
45        let result = null_array.into_array().cast(DType::Null).unwrap();
46        assert_eq!(result.len(), 5);
47        assert_eq!(result.dtype(), &DType::Null);
48    }
49
50    #[test]
51    fn test_cast_null_to_nullable_succeeds() {
52        let null_array = NullArray::new(5);
53        let result = null_array
54            .into_array()
55            .cast(DType::Primitive(PType::I32, Nullability::Nullable))
56            .unwrap();
57
58        // Should create a ConstantArray of nulls
59        assert_eq!(result.len(), 5);
60        assert_eq!(
61            result.dtype(),
62            &DType::Primitive(PType::I32, Nullability::Nullable)
63        );
64
65        // Verify all values are null
66        for i in 0..5 {
67            assert!(result.scalar_at(i).unwrap().is_null());
68        }
69    }
70
71    #[test]
72    fn test_cast_null_to_non_nullable_fails() {
73        let null_array = NullArray::new(5);
74        let result = null_array
75            .into_array()
76            .cast(DType::Primitive(PType::I32, Nullability::NonNullable));
77        assert!(result.is_err());
78    }
79
80    #[rstest]
81    #[case(NullArray::new(5))]
82    #[case(NullArray::new(1))]
83    #[case(NullArray::new(100))]
84    #[case(NullArray::new(0))]
85    fn test_cast_null_conformance(#[case] array: NullArray) {
86        test_cast_conformance(&array.into_array());
87    }
88}