Skip to main content

vortex_array/arrays/variant/vtable/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4mod operations;
5mod validity;
6
7use vortex_error::VortexExpect;
8use vortex_error::VortexResult;
9use vortex_error::vortex_ensure;
10use vortex_error::vortex_panic;
11use vortex_session::VortexSession;
12use vortex_session::registry::CachedId;
13
14use crate::ArrayRef;
15use crate::ExecutionCtx;
16use crate::ExecutionResult;
17use crate::array::Array;
18use crate::array::ArrayId;
19use crate::array::ArrayView;
20use crate::array::EmptyArrayData;
21use crate::array::VTable;
22use crate::arrays::variant::SLOT_NAMES;
23use crate::buffer::BufferHandle;
24use crate::dtype::DType;
25use crate::serde::ArrayChildren;
26
27/// A [`Variant`]-encoded Vortex array.
28pub type VariantArray = Array<Variant>;
29
30#[derive(Clone, Debug)]
31pub struct Variant;
32
33impl VTable for Variant {
34    type ArrayData = EmptyArrayData;
35
36    type OperationsVTable = Self;
37
38    type ValidityVTable = Self;
39
40    fn id(&self) -> ArrayId {
41        static ID: CachedId = CachedId::new("vortex.variant");
42        *ID
43    }
44
45    fn validate(
46        &self,
47        _data: &Self::ArrayData,
48        dtype: &DType,
49        len: usize,
50        slots: &[Option<ArrayRef>],
51    ) -> VortexResult<()> {
52        vortex_ensure!(
53            slots[0].is_some(),
54            "VariantArray child slot must be present"
55        );
56        let child = slots[0]
57            .as_ref()
58            .vortex_expect("validated child slot presence");
59        vortex_ensure!(
60            matches!(dtype, DType::Variant(_)),
61            "Expected Variant DType, got {dtype}"
62        );
63        vortex_ensure!(
64            child.dtype() == dtype,
65            "VariantArray child dtype {} does not match outer dtype {}",
66            child.dtype(),
67            dtype
68        );
69        vortex_ensure!(
70            child.len() == len,
71            "VariantArray length {} does not match outer length {}",
72            child.len(),
73            len
74        );
75        Ok(())
76    }
77
78    fn nbuffers(_array: ArrayView<'_, Self>) -> usize {
79        0
80    }
81
82    fn buffer(_array: ArrayView<'_, Self>, idx: usize) -> BufferHandle {
83        vortex_panic!("VariantArray buffer index {idx} out of bounds")
84    }
85
86    fn buffer_name(_array: ArrayView<'_, Self>, _idx: usize) -> Option<String> {
87        None
88    }
89
90    fn serialize(
91        _array: ArrayView<'_, Self>,
92        _session: &VortexSession,
93    ) -> VortexResult<Option<Vec<u8>>> {
94        Ok(Some(vec![]))
95    }
96
97    fn deserialize(
98        &self,
99        dtype: &DType,
100        len: usize,
101        metadata: &[u8],
102
103        _buffers: &[BufferHandle],
104        children: &dyn ArrayChildren,
105        _session: &VortexSession,
106    ) -> VortexResult<crate::array::ArrayParts<Self>> {
107        vortex_ensure!(
108            metadata.is_empty(),
109            "VariantArray expects empty metadata, got {} bytes",
110            metadata.len()
111        );
112        vortex_ensure!(matches!(dtype, DType::Variant(_)), "Expected Variant DType");
113        vortex_ensure!(
114            children.len() == 1,
115            "Expected 1 child, got {}",
116            children.len()
117        );
118        // The child carries the nullability for the whole VariantArray.
119        let child = children.get(0, dtype, len)?;
120        Ok(
121            crate::array::ArrayParts::new(self.clone(), dtype.clone(), len, EmptyArrayData)
122                .with_slots(vec![Some(child)]),
123        )
124    }
125
126    fn slot_name(_array: ArrayView<'_, Self>, idx: usize) -> String {
127        match SLOT_NAMES.get(idx) {
128            Some(name) => (*name).to_string(),
129            None => vortex_panic!("VariantArray slot_name index {idx} out of bounds"),
130        }
131    }
132
133    fn execute(array: Array<Self>, _ctx: &mut ExecutionCtx) -> VortexResult<ExecutionResult> {
134        Ok(ExecutionResult::done(array))
135    }
136}
137
138#[cfg(test)]
139mod tests {}