use arrow::array::BooleanArray;
use arrow::buffer::{BooleanBuffer, NullBuffer};
#[inline]
pub(crate) fn build_in_list_result<C>(
len: usize,
needle_nulls: Option<&NullBuffer>,
haystack_has_nulls: bool,
negated: bool,
contains: C,
) -> BooleanArray
where
C: FnMut(usize) -> bool,
{
let contains_buf = BooleanBuffer::collect_bool(len, contains);
build_result_from_contains(needle_nulls, haystack_has_nulls, negated, contains_buf)
}
#[inline]
pub(crate) fn build_result_from_contains(
needle_nulls: Option<&NullBuffer>,
haystack_has_nulls: bool,
negated: bool,
contains_buf: BooleanBuffer,
) -> BooleanArray {
match (needle_nulls, haystack_has_nulls, negated) {
(Some(v), true, false) => {
let values = v.inner() & &contains_buf;
BooleanArray::new(values.clone(), Some(NullBuffer::new(values)))
}
(None, true, false) => {
BooleanArray::new(contains_buf.clone(), Some(NullBuffer::new(contains_buf)))
}
(Some(v), true, true) => {
let valid = v.inner();
let values = valid & &(!&contains_buf);
let nulls = valid & &contains_buf;
BooleanArray::new(values, Some(NullBuffer::new(nulls)))
}
(None, true, true) => {
BooleanArray::new(!&contains_buf, Some(NullBuffer::new(contains_buf)))
}
(Some(v), false, false) => {
BooleanArray::new(v.inner() & &contains_buf, Some(v.clone()))
}
(Some(v), false, true) => {
BooleanArray::new(v.inner() & &(!&contains_buf), Some(v.clone()))
}
(None, false, false) => BooleanArray::new(contains_buf, None),
(None, false, true) => BooleanArray::new(!&contains_buf, None),
}
}