Skip to main content

vortex_array/arrays/struct_/vtable/
operations.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use vortex_error::VortexResult;
5use vortex_error::vortex_err;
6
7use crate::ExecutionCtx;
8use crate::array::ArrayView;
9use crate::array::OperationsVTable;
10use crate::array::ProbeState;
11use crate::arrays::Struct;
12use crate::arrays::struct_::StructArrayExt;
13use crate::arrays::struct_::StructSlots;
14use crate::scalar::Scalar;
15use crate::scalar::ScalarValue;
16
17impl OperationsVTable<Struct> for Struct {
18    type ProbeState = ();
19
20    fn probe_scalar(
21        state: &mut ProbeState<'_, Struct>,
22        index: usize,
23        ctx: &mut ExecutionCtx,
24    ) -> VortexResult<Scalar> {
25        let array = state.array();
26        if !state.is_valid(index, ctx)? {
27            return Ok(Scalar::null(array.dtype().clone()));
28        }
29        let nfields = array.iter_unmasked_fields().len();
30        let mut field_values = Vec::with_capacity(nfields);
31        for field in 0..nfields {
32            let slot = StructSlots::FIELDS_OFFSET + field;
33            let value = state
34                .slot(slot)?
35                .ok_or_else(|| vortex_err!("Struct field slot {slot} is absent"))?
36                .execute_scalar(index, ctx)?;
37            field_values.push(value.into_value());
38        }
39        // SAFETY: The index is in-bounds and the row was checked valid above. Each field read
40        // returns a value with the field's own dtype.
41        Ok(unsafe {
42            Scalar::new_unchecked(
43                array.dtype().clone(),
44                Some(ScalarValue::Tuple(field_values)),
45            )
46        })
47    }
48
49    fn scalar_at(
50        array: ArrayView<'_, Struct>,
51        index: usize,
52        ctx: &mut ExecutionCtx,
53    ) -> VortexResult<Scalar> {
54        Self::probe_scalar(&mut ProbeState::once(array), index, ctx)
55    }
56}