1use crate::arity::{binary, unary};
21use arrow_array::*;
22use arrow_buffer::ArrowNativeType;
23use arrow_schema::ArrowError;
24use num::traits::{WrappingShl, WrappingShr};
25use std::ops::{BitAnd, BitOr, BitXor, Not};
26
27fn bitwise_op<T, F>(
29 left: &PrimitiveArray<T>,
30 right: &PrimitiveArray<T>,
31 op: F,
32) -> Result<PrimitiveArray<T>, ArrowError>
33where
34 T: ArrowNumericType,
35 F: Fn(T::Native, T::Native) -> T::Native,
36{
37 binary(left, right, op)
38}
39
40pub fn bitwise_and<T>(
43 left: &PrimitiveArray<T>,
44 right: &PrimitiveArray<T>,
45) -> Result<PrimitiveArray<T>, ArrowError>
46where
47 T: ArrowNumericType,
48 T::Native: BitAnd<Output = T::Native>,
49{
50 bitwise_op(left, right, |a, b| a & b)
51}
52
53pub fn bitwise_or<T>(
56 left: &PrimitiveArray<T>,
57 right: &PrimitiveArray<T>,
58) -> Result<PrimitiveArray<T>, ArrowError>
59where
60 T: ArrowNumericType,
61 T::Native: BitOr<Output = T::Native>,
62{
63 bitwise_op(left, right, |a, b| a | b)
64}
65
66pub fn bitwise_xor<T>(
69 left: &PrimitiveArray<T>,
70 right: &PrimitiveArray<T>,
71) -> Result<PrimitiveArray<T>, ArrowError>
72where
73 T: ArrowNumericType,
74 T::Native: BitXor<Output = T::Native>,
75{
76 bitwise_op(left, right, |a, b| a ^ b)
77}
78
79pub fn bitwise_shift_left<T>(
82 left: &PrimitiveArray<T>,
83 right: &PrimitiveArray<T>,
84) -> Result<PrimitiveArray<T>, ArrowError>
85where
86 T: ArrowNumericType,
87 T::Native: WrappingShl<Output = T::Native>,
88{
89 bitwise_op(left, right, |a, b| {
90 let b = b.as_usize();
91 a.wrapping_shl(b as u32)
92 })
93}
94
95pub fn bitwise_shift_right<T>(
98 left: &PrimitiveArray<T>,
99 right: &PrimitiveArray<T>,
100) -> Result<PrimitiveArray<T>, ArrowError>
101where
102 T: ArrowNumericType,
103 T::Native: WrappingShr<Output = T::Native>,
104{
105 bitwise_op(left, right, |a, b| {
106 let b = b.as_usize();
107 a.wrapping_shr(b as u32)
108 })
109}
110
111pub fn bitwise_not<T>(array: &PrimitiveArray<T>) -> Result<PrimitiveArray<T>, ArrowError>
114where
115 T: ArrowNumericType,
116 T::Native: Not<Output = T::Native>,
117{
118 Ok(unary(array, |value| !value))
119}
120
121pub fn bitwise_and_not<T>(
124 left: &PrimitiveArray<T>,
125 right: &PrimitiveArray<T>,
126) -> Result<PrimitiveArray<T>, ArrowError>
127where
128 T: ArrowNumericType,
129 T::Native: BitAnd<Output = T::Native>,
130 T::Native: Not<Output = T::Native>,
131{
132 bitwise_op(left, right, |a, b| a & !b)
133}
134
135pub fn bitwise_and_scalar<T>(
138 array: &PrimitiveArray<T>,
139 scalar: T::Native,
140) -> Result<PrimitiveArray<T>, ArrowError>
141where
142 T: ArrowNumericType,
143 T::Native: BitAnd<Output = T::Native>,
144{
145 Ok(unary(array, |value| value & scalar))
146}
147
148pub fn bitwise_or_scalar<T>(
151 array: &PrimitiveArray<T>,
152 scalar: T::Native,
153) -> Result<PrimitiveArray<T>, ArrowError>
154where
155 T: ArrowNumericType,
156 T::Native: BitOr<Output = T::Native>,
157{
158 Ok(unary(array, |value| value | scalar))
159}
160
161pub fn bitwise_xor_scalar<T>(
164 array: &PrimitiveArray<T>,
165 scalar: T::Native,
166) -> Result<PrimitiveArray<T>, ArrowError>
167where
168 T: ArrowNumericType,
169 T::Native: BitXor<Output = T::Native>,
170{
171 Ok(unary(array, |value| value ^ scalar))
172}
173
174pub fn bitwise_shift_left_scalar<T>(
177 array: &PrimitiveArray<T>,
178 scalar: T::Native,
179) -> Result<PrimitiveArray<T>, ArrowError>
180where
181 T: ArrowNumericType,
182 T::Native: WrappingShl<Output = T::Native>,
183{
184 Ok(unary(array, |value| {
185 let scalar = scalar.as_usize();
186 value.wrapping_shl(scalar as u32)
187 }))
188}
189
190pub fn bitwise_shift_right_scalar<T>(
193 array: &PrimitiveArray<T>,
194 scalar: T::Native,
195) -> Result<PrimitiveArray<T>, ArrowError>
196where
197 T: ArrowNumericType,
198 T::Native: WrappingShr<Output = T::Native>,
199{
200 Ok(unary(array, |value| {
201 let scalar = scalar.as_usize();
202 value.wrapping_shr(scalar as u32)
203 }))
204}
205
206#[cfg(test)]
207mod tests {
208 use super::*;
209
210 #[test]
211 fn test_bitwise_and_array() -> Result<(), ArrowError> {
212 let left = UInt64Array::from(vec![Some(1), Some(2), None, Some(4)]);
214 let right = UInt64Array::from(vec![Some(5), Some(10), Some(8), Some(12)]);
215 let expected = UInt64Array::from(vec![Some(1), Some(2), None, Some(4)]);
216 let result = bitwise_and(&left, &right)?;
217 assert_eq!(expected, result);
218
219 let left = Int32Array::from(vec![Some(1), Some(2), None, Some(4)]);
221 let right = Int32Array::from(vec![Some(5), Some(-10), Some(8), Some(12)]);
222 let expected = Int32Array::from(vec![Some(1), Some(2), None, Some(4)]);
223 let result = bitwise_and(&left, &right)?;
224 assert_eq!(expected, result);
225 Ok(())
226 }
227
228 #[test]
229 fn test_bitwise_shift_left() {
230 let left = UInt64Array::from(vec![Some(1), Some(2), None, Some(4), Some(8)]);
231 let right = UInt64Array::from(vec![Some(5), Some(10), Some(8), Some(12), Some(u64::MAX)]);
232 let expected = UInt64Array::from(vec![Some(32), Some(2048), None, Some(16384), Some(0)]);
233 let result = bitwise_shift_left(&left, &right).unwrap();
234 assert_eq!(expected, result);
235 }
236
237 #[test]
238 fn test_bitwise_shift_left_scalar() {
239 let left = UInt64Array::from(vec![Some(1), Some(2), None, Some(4), Some(8)]);
240 let scalar = 2;
241 let expected = UInt64Array::from(vec![Some(4), Some(8), None, Some(16), Some(32)]);
242 let result = bitwise_shift_left_scalar(&left, scalar).unwrap();
243 assert_eq!(expected, result);
244 }
245
246 #[test]
247 fn test_bitwise_shift_right() {
248 let left = UInt64Array::from(vec![Some(32), Some(2048), None, Some(16384), Some(3)]);
249 let right = UInt64Array::from(vec![Some(5), Some(10), Some(8), Some(12), Some(65)]);
250 let expected = UInt64Array::from(vec![Some(1), Some(2), None, Some(4), Some(1)]);
251 let result = bitwise_shift_right(&left, &right).unwrap();
252 assert_eq!(expected, result);
253 }
254
255 #[test]
256 fn test_bitwise_shift_right_scalar() {
257 let left = UInt64Array::from(vec![Some(32), Some(2048), None, Some(16384), Some(3)]);
258 let scalar = 2;
259 let expected = UInt64Array::from(vec![Some(8), Some(512), None, Some(4096), Some(0)]);
260 let result = bitwise_shift_right_scalar(&left, scalar).unwrap();
261 assert_eq!(expected, result);
262 }
263
264 #[test]
265 fn test_bitwise_and_array_scalar() {
266 let left = UInt64Array::from(vec![Some(15), Some(2), None, Some(4)]);
268 let scalar = 7;
269 let expected = UInt64Array::from(vec![Some(7), Some(2), None, Some(4)]);
270 let result = bitwise_and_scalar(&left, scalar).unwrap();
271 assert_eq!(expected, result);
272
273 let left = Int32Array::from(vec![Some(1), Some(2), None, Some(4)]);
275 let scalar = -20;
276 let expected = Int32Array::from(vec![Some(0), Some(0), None, Some(4)]);
277 let result = bitwise_and_scalar(&left, scalar).unwrap();
278 assert_eq!(expected, result);
279 }
280
281 #[test]
282 fn test_bitwise_or_array() {
283 let left = UInt64Array::from(vec![Some(1), Some(2), None, Some(4)]);
285 let right = UInt64Array::from(vec![Some(7), Some(5), Some(8), Some(13)]);
286 let expected = UInt64Array::from(vec![Some(7), Some(7), None, Some(13)]);
287 let result = bitwise_or(&left, &right).unwrap();
288 assert_eq!(expected, result);
289
290 let left = Int32Array::from(vec![Some(1), Some(2), None, Some(4)]);
292 let right = Int32Array::from(vec![Some(-7), Some(-5), Some(8), Some(13)]);
293 let expected = Int32Array::from(vec![Some(-7), Some(-5), None, Some(13)]);
294 let result = bitwise_or(&left, &right).unwrap();
295 assert_eq!(expected, result);
296 }
297
298 #[test]
299 fn test_bitwise_not_array() {
300 let array = UInt64Array::from(vec![Some(1), Some(2), None, Some(4)]);
302 let expected = UInt64Array::from(vec![
303 Some(18446744073709551614),
304 Some(18446744073709551613),
305 None,
306 Some(18446744073709551611),
307 ]);
308 let result = bitwise_not(&array).unwrap();
309 assert_eq!(expected, result);
310 let array = Int32Array::from(vec![Some(1), Some(2), None, Some(4)]);
312 let expected = Int32Array::from(vec![Some(-2), Some(-3), None, Some(-5)]);
313 let result = bitwise_not(&array).unwrap();
314 assert_eq!(expected, result);
315 }
316
317 #[test]
318 fn test_bitwise_and_not_array() {
319 let left = UInt64Array::from(vec![Some(8), Some(2), None, Some(4)]);
321 let right = UInt64Array::from(vec![Some(7), Some(5), Some(8), Some(13)]);
322 let expected = UInt64Array::from(vec![Some(8), Some(2), None, Some(0)]);
323 let result = bitwise_and_not(&left, &right).unwrap();
324 assert_eq!(expected, result);
325 assert_eq!(
326 bitwise_and(&left, &bitwise_not(&right).unwrap()).unwrap(),
327 result
328 );
329
330 let left = Int32Array::from(vec![Some(2), Some(1), None, Some(3)]);
332 let right = Int32Array::from(vec![Some(-7), Some(-5), Some(8), Some(13)]);
333 let expected = Int32Array::from(vec![Some(2), Some(0), None, Some(2)]);
334 let result = bitwise_and_not(&left, &right).unwrap();
335 assert_eq!(expected, result);
336 assert_eq!(
337 bitwise_and(&left, &bitwise_not(&right).unwrap()).unwrap(),
338 result
339 );
340 }
341
342 #[test]
343 fn test_bitwise_or_array_scalar() {
344 let left = UInt64Array::from(vec![Some(15), Some(2), None, Some(4)]);
346 let scalar = 7;
347 let expected = UInt64Array::from(vec![Some(15), Some(7), None, Some(7)]);
348 let result = bitwise_or_scalar(&left, scalar).unwrap();
349 assert_eq!(expected, result);
350
351 let left = Int32Array::from(vec![Some(1), Some(2), None, Some(4)]);
353 let scalar = 20;
354 let expected = Int32Array::from(vec![Some(21), Some(22), None, Some(20)]);
355 let result = bitwise_or_scalar(&left, scalar).unwrap();
356 assert_eq!(expected, result);
357 }
358
359 #[test]
360 fn test_bitwise_xor_array() {
361 let left = UInt64Array::from(vec![Some(1), Some(2), None, Some(4)]);
363 let right = UInt64Array::from(vec![Some(7), Some(5), Some(8), Some(13)]);
364 let expected = UInt64Array::from(vec![Some(6), Some(7), None, Some(9)]);
365 let result = bitwise_xor(&left, &right).unwrap();
366 assert_eq!(expected, result);
367
368 let left = Int32Array::from(vec![Some(1), Some(2), None, Some(4)]);
370 let right = Int32Array::from(vec![Some(-7), Some(5), Some(8), Some(-13)]);
371 let expected = Int32Array::from(vec![Some(-8), Some(7), None, Some(-9)]);
372 let result = bitwise_xor(&left, &right).unwrap();
373 assert_eq!(expected, result);
374 }
375
376 #[test]
377 fn test_bitwise_xor_array_scalar() {
378 let left = UInt64Array::from(vec![Some(15), Some(2), None, Some(4)]);
380 let scalar = 7;
381 let expected = UInt64Array::from(vec![Some(8), Some(5), None, Some(3)]);
382 let result = bitwise_xor_scalar(&left, scalar).unwrap();
383 assert_eq!(expected, result);
384
385 let left = Int32Array::from(vec![Some(1), Some(2), None, Some(4)]);
387 let scalar = -20;
388 let expected = Int32Array::from(vec![Some(-19), Some(-18), None, Some(-24)]);
389 let result = bitwise_xor_scalar(&left, scalar).unwrap();
390 assert_eq!(expected, result);
391 }
392}