vortex_array/arrays/primitive/compute/
between.rs1use vortex_buffer::BitBuffer;
5use vortex_error::VortexExpect;
6use vortex_error::VortexResult;
7
8use crate::ArrayRef;
9use crate::ExecutionCtx;
10use crate::IntoArray;
11use crate::array::ArrayView;
12use crate::arrays::BoolArray;
13use crate::arrays::Primitive;
14use crate::dtype::NativePType;
15use crate::dtype::Nullability;
16use crate::match_each_native_ptype;
17use crate::scalar_fn::fns::between::BetweenKernel;
18use crate::scalar_fn::fns::between::BetweenOptions;
19use crate::scalar_fn::fns::between::StrictComparison;
20
21impl BetweenKernel for Primitive {
22 fn between(
23 arr: ArrayView<'_, Primitive>,
24 lower: &ArrayRef,
25 upper: &ArrayRef,
26 options: &BetweenOptions,
27 ctx: &mut ExecutionCtx,
28 ) -> VortexResult<Option<ArrayRef>> {
29 let (Some(lower), Some(upper)) = (lower.as_constant(), upper.as_constant()) else {
30 return Ok(None);
31 };
32
33 let nullability =
37 arr.dtype().nullability() | lower.dtype().nullability() | upper.dtype().nullability();
38
39 Ok(Some(match_each_native_ptype!(arr.ptype(), |P| {
40 between_impl::<P>(
41 arr,
42 P::try_from(&lower)?,
43 P::try_from(&upper)?,
44 nullability,
45 options,
46 ctx,
47 )
48 })))
49 }
50}
51
52fn between_impl<T: NativePType + Copy>(
53 arr: ArrayView<'_, Primitive>,
54 lower: T,
55 upper: T,
56 nullability: Nullability,
57 options: &BetweenOptions,
58 ctx: &mut ExecutionCtx,
59) -> ArrayRef {
60 match (options.lower_strict, options.upper_strict) {
61 (StrictComparison::Strict, StrictComparison::Strict) => between_impl_(
63 arr,
64 lower,
65 NativePType::is_lt,
66 upper,
67 NativePType::is_lt,
68 nullability,
69 ctx,
70 ),
71 (StrictComparison::Strict, StrictComparison::NonStrict) => between_impl_(
72 arr,
73 lower,
74 NativePType::is_lt,
75 upper,
76 NativePType::is_le,
77 nullability,
78 ctx,
79 ),
80 (StrictComparison::NonStrict, StrictComparison::Strict) => between_impl_(
81 arr,
82 lower,
83 NativePType::is_le,
84 upper,
85 NativePType::is_lt,
86 nullability,
87 ctx,
88 ),
89 (StrictComparison::NonStrict, StrictComparison::NonStrict) => between_impl_(
90 arr,
91 lower,
92 NativePType::is_le,
93 upper,
94 NativePType::is_le,
95 nullability,
96 ctx,
97 ),
98 }
99}
100
101fn between_impl_<T>(
102 arr: ArrayView<'_, Primitive>,
103 lower: T,
104 lower_fn: impl Fn(T, T) -> bool,
105 upper: T,
106 upper_fn: impl Fn(T, T) -> bool,
107 nullability: Nullability,
108 ctx: &mut ExecutionCtx,
109) -> ArrayRef
110where
111 T: NativePType + Copy,
112{
113 let slice = arr.as_slice::<T>();
114 BoolArray::new(
115 BitBuffer::collect_bool_multiversioned_in(
116 slice.len(),
117 |idx| {
118 let i = unsafe { *slice.get_unchecked(idx) };
120 lower_fn(lower, i) & upper_fn(i, upper)
121 },
122 ctx.allocator().clone(),
123 ),
124 arr.validity()
125 .vortex_expect("validity should be derivable")
126 .union_nullability(nullability),
127 )
128 .into_array()
129}