Skip to main content

vortex_array/arrays/primitive/compute/
rules.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use vortex_dtype::match_each_native_ptype;
5use vortex_error::VortexResult;
6
7use crate::ArrayRef;
8use crate::IntoArray;
9use crate::arrays::MaskedArray;
10use crate::arrays::MaskedVTable;
11use crate::arrays::PrimitiveArray;
12use crate::arrays::PrimitiveVTable;
13use crate::arrays::SliceReduceAdaptor;
14use crate::compute::MaskReduceAdaptor;
15use crate::optimizer::rules::ArrayParentReduceRule;
16use crate::optimizer::rules::ParentRuleSet;
17use crate::vtable::ValidityHelper;
18
19pub(crate) const RULES: ParentRuleSet<PrimitiveVTable> = ParentRuleSet::new(&[
20    ParentRuleSet::lift(&PrimitiveMaskedValidityRule),
21    ParentRuleSet::lift(&MaskReduceAdaptor(PrimitiveVTable)),
22    ParentRuleSet::lift(&SliceReduceAdaptor(PrimitiveVTable)),
23]);
24
25/// Rule to push down validity masking from MaskedArray parent into PrimitiveArray child.
26///
27/// When a PrimitiveArray is wrapped by a MaskedArray, this rule merges the mask's validity
28/// with the PrimitiveArray's existing validity, eliminating the need for the MaskedArray wrapper.
29#[derive(Default, Debug)]
30pub struct PrimitiveMaskedValidityRule;
31
32impl ArrayParentReduceRule<PrimitiveVTable> for PrimitiveMaskedValidityRule {
33    type Parent = MaskedVTable;
34
35    fn reduce_parent(
36        &self,
37        array: &PrimitiveArray,
38        parent: &MaskedArray,
39        _child_idx: usize,
40    ) -> VortexResult<Option<ArrayRef>> {
41        // Merge the parent's validity mask into the child's validity
42        // TODO(joe): make this lazy
43        let masked_array = match_each_native_ptype!(array.ptype(), |T| {
44            // SAFETY: masking validity does not change PrimitiveArray invariants
45            unsafe {
46                PrimitiveArray::new_unchecked_from_handle(
47                    array.buffer_handle().clone(),
48                    array.ptype(),
49                    array.validity().clone().and(parent.validity().clone())?,
50                )
51            }
52            .into_array()
53        });
54
55        Ok(Some(masked_array))
56    }
57}