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::array::ArrayView;
10use crate::arrays::ConstantArray;
11use crate::arrays::Null;
12use crate::dtype::DType;
13use crate::scalar::Scalar;
14use crate::scalar_fn::fns::cast::CastReduce;
15
16impl CastReduce for Null {
17    fn cast(array: ArrayView<'_, Null>, 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.array().clone()));
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::LEGACY_SESSION;
36    use crate::VortexSessionExecute;
37    use crate::arrays::NullArray;
38    use crate::builtins::ArrayBuiltins;
39    use crate::compute::conformance::cast::test_cast_conformance;
40    use crate::dtype::DType;
41    use crate::dtype::Nullability;
42    use crate::dtype::PType;
43
44    #[test]
45    fn test_cast_null_to_null() {
46        let null_array = NullArray::new(5);
47        let result = null_array.into_array().cast(DType::Null).unwrap();
48        assert_eq!(result.len(), 5);
49        assert_eq!(result.dtype(), &DType::Null);
50    }
51
52    #[test]
53    fn test_cast_null_to_nullable_succeeds() {
54        let null_array = NullArray::new(5);
55        let result = null_array
56            .into_array()
57            .cast(DType::Primitive(PType::I32, Nullability::Nullable))
58            .unwrap();
59
60        // Should create a ConstantArray of nulls
61        assert_eq!(result.len(), 5);
62        assert_eq!(
63            result.dtype(),
64            &DType::Primitive(PType::I32, Nullability::Nullable)
65        );
66
67        // Verify all values are null
68        for i in 0..5 {
69            assert!(
70                result
71                    .execute_scalar(i, &mut LEGACY_SESSION.create_execution_ctx())
72                    .unwrap()
73                    .is_null()
74            );
75        }
76    }
77
78    #[test]
79    fn test_cast_null_to_non_nullable_fails() {
80        let null_array = NullArray::new(5);
81        let result = null_array
82            .into_array()
83            .cast(DType::Primitive(PType::I32, Nullability::NonNullable));
84        assert!(result.is_err());
85    }
86
87    #[rstest]
88    #[case(NullArray::new(5))]
89    #[case(NullArray::new(1))]
90    #[case(NullArray::new(100))]
91    #[case(NullArray::new(0))]
92    fn test_cast_null_conformance(#[case] array: NullArray) {
93        test_cast_conformance(&array.into_array());
94    }
95}