use arrow_array::BooleanArray;
use vortex_dtype::DType;
use vortex_error::VortexResult;
use vortex_error::vortex_bail;
use vortex_mask::Mask;
use crate::Array;
use crate::ArrayRef;
use crate::IntoArray;
use crate::ToCanonical;
use crate::arrow::FromArrowArray;
use crate::arrow::IntoArrowArray;
use crate::builtins::ArrayBuiltins;
use crate::scalar::Scalar;
pub fn filter(array: &dyn Array, mask: &Mask) -> VortexResult<ArrayRef> {
Ok(array.filter(mask.clone())?.to_canonical()?.into_array())
}
impl dyn Array + '_ {
pub fn try_to_mask_fill_null_false(&self) -> VortexResult<Mask> {
if !matches!(self.dtype(), DType::Bool(_)) {
vortex_bail!("mask must be bool array, has dtype {}", self.dtype());
}
let array = self
.to_array()
.fill_null(Scalar::bool(false, self.dtype().nullability()))?;
Ok(array.to_bool().to_mask_fill_null_false())
}
}
pub fn arrow_filter_fn(array: &dyn Array, mask: &Mask) -> VortexResult<ArrayRef> {
let values = match &mask {
Mask::Values(values) => values,
Mask::AllTrue(_) | Mask::AllFalse(_) => unreachable!("check in filter invoke"),
};
let array_ref = array.to_array().into_arrow_preferred()?;
let mask_array = BooleanArray::new(values.bit_buffer().clone().into(), None);
let filtered = arrow_select::filter::filter(array_ref.as_ref(), &mask_array)?;
ArrayRef::from_arrow(filtered.as_ref(), array.dtype().is_nullable())
}