1use std::ops::BitAnd;
10use std::ops::BitOr;
11
12use vortex_buffer::BitBuffer;
13use vortex_vector::BoolDatum;
14use vortex_vector::ScalarOps;
15use vortex_vector::VectorMutOps;
16use vortex_vector::VectorOps;
17use vortex_vector::bool::BoolScalar;
18use vortex_vector::bool::BoolVector;
19
20use super::LogicalAnd;
21use super::LogicalAndNot;
22use super::LogicalOp;
23use super::LogicalOr;
24
25pub struct And;
27
28pub struct Or;
30
31pub struct AndNot;
33
34pub trait LogicalBinaryOp {
38 fn bit_op(lhs: &BitBuffer, rhs: &BitBuffer) -> BitBuffer;
40
41 fn scalar_op(lhs: bool, rhs: bool) -> bool;
43}
44
45impl LogicalBinaryOp for And {
46 fn bit_op(lhs: &BitBuffer, rhs: &BitBuffer) -> BitBuffer {
47 lhs.bitand(rhs)
48 }
49
50 fn scalar_op(lhs: bool, rhs: bool) -> bool {
51 lhs && rhs
52 }
53}
54
55impl LogicalBinaryOp for Or {
56 fn bit_op(lhs: &BitBuffer, rhs: &BitBuffer) -> BitBuffer {
57 lhs.bitor(rhs)
58 }
59
60 fn scalar_op(lhs: bool, rhs: bool) -> bool {
61 lhs || rhs
62 }
63}
64
65impl LogicalBinaryOp for AndNot {
66 fn bit_op(lhs: &BitBuffer, rhs: &BitBuffer) -> BitBuffer {
67 lhs.bitand_not(rhs)
68 }
69
70 fn scalar_op(lhs: bool, rhs: bool) -> bool {
71 lhs && !rhs
72 }
73}
74
75impl LogicalOp<And> for &BoolScalar {
80 type Output = BoolScalar;
81
82 fn op(self, rhs: &BoolScalar) -> BoolScalar {
83 binary_scalar_op::<And>(self, rhs)
84 }
85}
86
87impl LogicalOp<Or> for &BoolScalar {
88 type Output = BoolScalar;
89
90 fn op(self, rhs: &BoolScalar) -> BoolScalar {
91 binary_scalar_op::<Or>(self, rhs)
92 }
93}
94
95impl LogicalOp<AndNot> for &BoolScalar {
96 type Output = BoolScalar;
97
98 fn op(self, rhs: &BoolScalar) -> BoolScalar {
99 binary_scalar_op::<AndNot>(self, rhs)
100 }
101}
102
103impl LogicalOp<And> for &BoolVector {
104 type Output = BoolVector;
105
106 fn op(self, rhs: &BoolVector) -> BoolVector {
107 binary_vector_op::<And>(self, rhs)
108 }
109}
110
111impl LogicalOp<Or> for &BoolVector {
112 type Output = BoolVector;
113
114 fn op(self, rhs: &BoolVector) -> BoolVector {
115 binary_vector_op::<Or>(self, rhs)
116 }
117}
118
119impl LogicalOp<AndNot> for &BoolVector {
120 type Output = BoolVector;
121
122 fn op(self, rhs: &BoolVector) -> BoolVector {
123 binary_vector_op::<AndNot>(self, rhs)
124 }
125}
126
127impl LogicalOp<And, &BoolDatum> for &BoolDatum {
128 type Output = BoolDatum;
129
130 fn op(self, rhs: &BoolDatum) -> BoolDatum {
131 binary_datum_op::<And>(self, rhs)
132 }
133}
134
135impl LogicalOp<Or, &BoolDatum> for &BoolDatum {
136 type Output = BoolDatum;
137
138 fn op(self, rhs: &BoolDatum) -> BoolDatum {
139 binary_datum_op::<Or>(self, rhs)
140 }
141}
142
143impl LogicalOp<AndNot, &BoolDatum> for &BoolDatum {
144 type Output = BoolDatum;
145
146 fn op(self, rhs: &BoolDatum) -> BoolDatum {
147 binary_datum_op::<AndNot>(self, rhs)
148 }
149}
150
151fn binary_scalar_op<Op: LogicalBinaryOp>(lhs: &BoolScalar, rhs: &BoolScalar) -> BoolScalar {
156 let result = match (lhs.value(), rhs.value()) {
157 (Some(a), Some(b)) => Some(Op::scalar_op(a, b)),
158 _ => None, };
160 BoolScalar::new(result)
161}
162
163fn binary_vector_op<Op: LogicalBinaryOp>(lhs: &BoolVector, rhs: &BoolVector) -> BoolVector {
164 assert_eq!(lhs.len(), rhs.len());
165
166 BoolVector::new(
167 Op::bit_op(lhs.bits(), rhs.bits()),
168 lhs.validity().bitand(rhs.validity()),
169 )
170}
171
172fn binary_datum_op<Op: LogicalBinaryOp>(lhs: &BoolDatum, rhs: &BoolDatum) -> BoolDatum
173where
174 for<'a> &'a BoolScalar: LogicalOp<Op, Output = BoolScalar>,
175 for<'a> &'a BoolVector: LogicalOp<Op, Output = BoolVector>,
176{
177 match (lhs, rhs) {
178 (BoolDatum::Vector(lhs), BoolDatum::Vector(rhs)) => {
179 BoolDatum::Vector(<&BoolVector as LogicalOp<Op>>::op(lhs, rhs))
180 }
181 (BoolDatum::Scalar(lhs), BoolDatum::Scalar(rhs)) => {
182 BoolDatum::Scalar(<&BoolScalar as LogicalOp<Op>>::op(lhs, rhs))
183 }
184 (BoolDatum::Scalar(sc), BoolDatum::Vector(vec)) => {
185 let expanded = sc.repeat(vec.len()).freeze().into_bool();
186 BoolDatum::Vector(<&BoolVector as LogicalOp<Op>>::op(&expanded, vec))
187 }
188 (BoolDatum::Vector(vec), BoolDatum::Scalar(sc)) => {
189 let expanded = sc.repeat(vec.len()).freeze().into_bool();
190 BoolDatum::Vector(<&BoolVector as LogicalOp<Op>>::op(vec, &expanded))
191 }
192 }
193}
194
195impl LogicalAnd for &BoolScalar {
200 type Output = BoolScalar;
201
202 fn and(self, other: &BoolScalar) -> BoolScalar {
203 binary_scalar_op::<And>(self, other)
204 }
205}
206
207impl LogicalAnd for &BoolVector {
208 type Output = BoolVector;
209
210 fn and(self, other: &BoolVector) -> BoolVector {
211 binary_vector_op::<And>(self, other)
212 }
213}
214
215impl LogicalAnd<&BoolDatum> for &BoolDatum {
216 type Output = BoolDatum;
217
218 fn and(self, other: &BoolDatum) -> BoolDatum {
219 <&BoolDatum as LogicalOp<And, &BoolDatum>>::op(self, other)
220 }
221}
222
223impl LogicalOr for &BoolScalar {
224 type Output = BoolScalar;
225
226 fn or(self, other: &BoolScalar) -> BoolScalar {
227 binary_scalar_op::<Or>(self, other)
228 }
229}
230
231impl LogicalOr for &BoolVector {
232 type Output = BoolVector;
233
234 fn or(self, other: &BoolVector) -> BoolVector {
235 binary_vector_op::<Or>(self, other)
236 }
237}
238
239impl LogicalOr<&BoolDatum> for &BoolDatum {
240 type Output = BoolDatum;
241
242 fn or(self, other: &BoolDatum) -> BoolDatum {
243 <&BoolDatum as LogicalOp<Or, &BoolDatum>>::op(self, other)
244 }
245}
246
247impl LogicalAndNot for &BoolScalar {
248 type Output = BoolScalar;
249
250 fn and_not(self, other: &BoolScalar) -> BoolScalar {
251 binary_scalar_op::<AndNot>(self, other)
252 }
253}
254
255impl LogicalAndNot for &BoolVector {
256 type Output = BoolVector;
257
258 fn and_not(self, other: &BoolVector) -> BoolVector {
259 binary_vector_op::<AndNot>(self, other)
260 }
261}
262
263impl LogicalAndNot<&BoolDatum> for &BoolDatum {
264 type Output = BoolDatum;
265
266 fn and_not(self, other: &BoolDatum) -> BoolDatum {
267 <&BoolDatum as LogicalOp<AndNot, &BoolDatum>>::op(self, other)
268 }
269}
270
271#[cfg(test)]
272mod tests {
273 use vortex_buffer::bitbuffer;
274 use vortex_mask::Mask;
275 use vortex_vector::bool::BoolScalar;
276 use vortex_vector::bool::BoolVector;
277
278 use super::*;
279
280 #[test]
283 fn test_and_basic() {
284 let left = BoolVector::new(bitbuffer![1 1 0 0], Mask::new_true(4));
285 let right = BoolVector::new(bitbuffer![1 0 1 0], Mask::new_true(4));
286
287 let result = left.and(&right);
288 assert_eq!(result.bits(), &bitbuffer![1 0 0 0]);
289 }
290
291 #[test]
292 fn test_and_with_nulls() {
293 let left = BoolVector::new(bitbuffer![1 0], Mask::from(bitbuffer![1 0]));
294 let right = BoolVector::new(bitbuffer![1 1], Mask::new_true(2));
295
296 let result = left.and(&right);
297 assert_eq!(result.validity(), &Mask::from(bitbuffer![1 0]));
299 }
300
301 #[test]
302 fn test_and_scalar() {
303 let left = BoolScalar::new(Some(true));
304 let right = BoolScalar::new(Some(false));
305 assert_eq!((&left).and(&right).value(), Some(false));
306
307 let left = BoolScalar::new(Some(true));
308 let right = BoolScalar::new(Some(true));
309 assert_eq!((&left).and(&right).value(), Some(true));
310
311 let left = BoolScalar::new(Some(true));
312 let right = BoolScalar::new(None);
313 assert_eq!((&left).and(&right).value(), None);
314 }
315
316 #[test]
319 fn test_or_basic() {
320 let left = BoolVector::new(bitbuffer![1 1 0 0], Mask::new_true(4));
321 let right = BoolVector::new(bitbuffer![1 0 1 0], Mask::new_true(4));
322
323 let result = left.or(&right);
324 assert_eq!(result.bits(), &bitbuffer![1 1 1 0]);
325 }
326
327 #[test]
328 fn test_or_with_nulls() {
329 let left = BoolVector::new(bitbuffer![0 1], Mask::from(bitbuffer![0 1]));
330 let right = BoolVector::new(bitbuffer![0 0], Mask::new_true(2));
331
332 let result = left.or(&right);
333 assert_eq!(result.validity(), &Mask::from(bitbuffer![0 1]));
335 }
336
337 #[test]
338 fn test_or_scalar() {
339 let left = BoolScalar::new(Some(true));
340 let right = BoolScalar::new(Some(false));
341 assert_eq!((&left).or(&right).value(), Some(true));
342
343 let left = BoolScalar::new(Some(false));
344 let right = BoolScalar::new(Some(false));
345 assert_eq!((&left).or(&right).value(), Some(false));
346
347 let left = BoolScalar::new(Some(false));
348 let right = BoolScalar::new(None);
349 assert_eq!((&left).or(&right).value(), None);
350 }
351
352 #[test]
355 fn test_and_not_basic() {
356 let left = BoolVector::new(bitbuffer![1 1 0 0], Mask::new_true(4));
358 let right = BoolVector::new(bitbuffer![1 0 1 0], Mask::new_true(4));
359
360 let result = left.and_not(&right);
361 assert_eq!(result.bits(), &bitbuffer![0 1 0 0]);
363 }
364
365 #[test]
366 fn test_and_not_all_true() {
367 let left = BoolVector::new(bitbuffer![1 1], Mask::new_true(2));
368 let right = BoolVector::new(bitbuffer![1 1], Mask::new_true(2));
369
370 let result = left.and_not(&right);
371 assert_eq!(result.bits(), &bitbuffer![0 0]);
372 }
373
374 #[test]
375 fn test_and_not_scalar() {
376 let left = BoolScalar::new(Some(true));
377 let right = BoolScalar::new(Some(true));
378 assert_eq!((&left).and_not(&right).value(), Some(false));
379
380 let left = BoolScalar::new(Some(true));
381 let right = BoolScalar::new(Some(false));
382 assert_eq!((&left).and_not(&right).value(), Some(true));
383
384 let left = BoolScalar::new(Some(true));
385 let right = BoolScalar::new(None);
386 assert_eq!((&left).and_not(&right).value(), None);
387 }
388
389 #[test]
392 fn test_datum_and_vector_vector() {
393 let left = BoolDatum::Vector(BoolVector::new(bitbuffer![1 1 0 0], Mask::new_true(4)));
394 let right = BoolDatum::Vector(BoolVector::new(bitbuffer![1 0 1 0], Mask::new_true(4)));
395
396 let result = left.and(&right);
397 let BoolDatum::Vector(vec) = result else {
398 panic!("Expected Vector");
399 };
400 assert_eq!(vec.bits(), &bitbuffer![1 0 0 0]);
401 }
402
403 #[test]
404 fn test_datum_and_scalar_scalar() {
405 let left = BoolDatum::Scalar(BoolScalar::new(Some(true)));
406 let right = BoolDatum::Scalar(BoolScalar::new(Some(false)));
407
408 let result = left.and(&right);
409 let BoolDatum::Scalar(sc) = result else {
410 panic!("Expected Scalar");
411 };
412 assert_eq!(sc.value(), Some(false));
413 }
414
415 #[test]
416 fn test_datum_and_scalar_vector() {
417 let left = BoolDatum::Scalar(BoolScalar::new(Some(true)));
418 let right = BoolDatum::Vector(BoolVector::new(bitbuffer![1 0 1 0], Mask::new_true(4)));
419
420 let result = left.and(&right);
421 let BoolDatum::Vector(vec) = result else {
422 panic!("Expected Vector");
423 };
424 assert_eq!(vec.bits(), &bitbuffer![1 0 1 0]);
425 }
426
427 #[test]
428 fn test_datum_or_vector_scalar() {
429 let left = BoolDatum::Vector(BoolVector::new(bitbuffer![1 0 1 0], Mask::new_true(4)));
430 let right = BoolDatum::Scalar(BoolScalar::new(Some(true)));
431
432 let result = left.or(&right);
433 let BoolDatum::Vector(vec) = result else {
434 panic!("Expected Vector");
435 };
436 assert_eq!(vec.bits(), &bitbuffer![1 1 1 1]);
437 }
438}