@@ -334,6 +334,141 @@ fn modulus_decimal(left: &DecimalArray, right: &DecimalArray) -> Result<DecimalA
334334    Ok ( decimal_builder. finish ( ) ) 
335335} 
336336
337+ fn  bitwise_and ( left :  ArrayRef ,  right :  ArrayRef )  -> Result < ArrayRef >  { 
338+     let  len = left. len ( ) ; 
339+     match  & left. data_type ( )  { 
340+         DataType :: Int8  => { 
341+             let  left = left. as_any ( ) . downcast_ref :: < Int8Array > ( ) . unwrap ( ) ; 
342+             let  right = right. as_any ( ) . downcast_ref :: < Int8Array > ( ) . unwrap ( ) ; 
343+             let  result = ( 0 ..len) 
344+                 . into_iter ( ) 
345+                 . map ( |i| { 
346+                     if  left. is_null ( i)  || right. is_null ( i)  { 
347+                         None 
348+                     }  else  { 
349+                         Some ( left. value ( i)  &  right. value ( i) ) 
350+                     } 
351+                 } ) 
352+                 . collect :: < Int8Array > ( ) ; 
353+             Ok ( Arc :: new ( result) ) 
354+         } 
355+         DataType :: Int16  => { 
356+             let  left = left. as_any ( ) . downcast_ref :: < Int16Array > ( ) . unwrap ( ) ; 
357+             let  right = right. as_any ( ) . downcast_ref :: < Int16Array > ( ) . unwrap ( ) ; 
358+             let  result = ( 0 ..len) 
359+                 . into_iter ( ) 
360+                 . map ( |i| { 
361+                     if  left. is_null ( i)  || right. is_null ( i)  { 
362+                         None 
363+                     }  else  { 
364+                         Some ( left. value ( i)  &  right. value ( i) ) 
365+                     } 
366+                 } ) 
367+                 . collect :: < Int16Array > ( ) ; 
368+             Ok ( Arc :: new ( result) ) 
369+         } 
370+         DataType :: Int32  => { 
371+             let  left = left. as_any ( ) . downcast_ref :: < Int32Array > ( ) . unwrap ( ) ; 
372+             let  right = right. as_any ( ) . downcast_ref :: < Int32Array > ( ) . unwrap ( ) ; 
373+             let  result = ( 0 ..len) 
374+                 . into_iter ( ) 
375+                 . map ( |i| { 
376+                     if  left. is_null ( i)  || right. is_null ( i)  { 
377+                         None 
378+                     }  else  { 
379+                         Some ( left. value ( i)  &  right. value ( i) ) 
380+                     } 
381+                 } ) 
382+                 . collect :: < Int32Array > ( ) ; 
383+             Ok ( Arc :: new ( result) ) 
384+         } 
385+         DataType :: Int64  => { 
386+             let  left = left. as_any ( ) . downcast_ref :: < Int64Array > ( ) . unwrap ( ) ; 
387+             let  right = right. as_any ( ) . downcast_ref :: < Int64Array > ( ) . unwrap ( ) ; 
388+             let  result = ( 0 ..len) 
389+                 . into_iter ( ) 
390+                 . map ( |i| { 
391+                     if  left. is_null ( i)  || right. is_null ( i)  { 
392+                         None 
393+                     }  else  { 
394+                         Some ( left. value ( i)  &  right. value ( i) ) 
395+                     } 
396+                 } ) 
397+                 . collect :: < Int64Array > ( ) ; 
398+             Ok ( Arc :: new ( result) ) 
399+         } 
400+         other => Err ( DataFusionError :: Internal ( format ! ( 
401+             "Data type {:?} not supported for binary operation '{}' on dyn arrays" , 
402+             other, 
403+             Operator :: BitwiseAnd 
404+         ) ) ) , 
405+     } 
406+ } 
407+ 
408+ fn  bitwise_and_scalar ( array :  & ArrayRef ,  scalar :  ScalarValue )  -> Option < Result < ArrayRef > >  { 
409+     let  len = array. len ( ) ; 
410+     let  result = match  array. data_type ( )  { 
411+         DataType :: Int8  => { 
412+             let  array = array. as_any ( ) . downcast_ref :: < Int8Array > ( ) . unwrap ( ) ; 
413+             if  scalar. is_null ( )  { 
414+                 Ok ( new_null_array ( array. data_type ( ) ,  len) ) 
415+             }  else  { 
416+                 let  right:  i8  = scalar. try_into ( ) . unwrap ( ) ; 
417+                 let  result = ( 0 ..len) 
418+                     . into_iter ( ) 
419+                     . map ( |i| Some ( array. value ( i)  &  right) ) 
420+                     . collect :: < Int8Array > ( ) ; 
421+                 Ok ( Arc :: new ( result)  as  ArrayRef ) 
422+             } 
423+         } 
424+         DataType :: Int16  => { 
425+             let  array = array. as_any ( ) . downcast_ref :: < Int16Array > ( ) . unwrap ( ) ; 
426+             if  scalar. is_null ( )  { 
427+                 Ok ( new_null_array ( array. data_type ( ) ,  len) ) 
428+             }  else  { 
429+                 let  right:  i16  = scalar. try_into ( ) . unwrap ( ) ; 
430+                 let  result = ( 0 ..len) 
431+                     . into_iter ( ) 
432+                     . map ( |i| Some ( array. value ( i)  &  right) ) 
433+                     . collect :: < Int16Array > ( ) ; 
434+                 Ok ( Arc :: new ( result)  as  ArrayRef ) 
435+             } 
436+         } 
437+         DataType :: Int32  => { 
438+             let  array = array. as_any ( ) . downcast_ref :: < Int32Array > ( ) . unwrap ( ) ; 
439+             if  scalar. is_null ( )  { 
440+                 Ok ( new_null_array ( array. data_type ( ) ,  len) ) 
441+             }  else  { 
442+                 let  right:  i32  = scalar. try_into ( ) . unwrap ( ) ; 
443+                 let  result = ( 0 ..len) 
444+                     . into_iter ( ) 
445+                     . map ( |i| Some ( array. value ( i)  &  right) ) 
446+                     . collect :: < Int32Array > ( ) ; 
447+                 Ok ( Arc :: new ( result)  as  ArrayRef ) 
448+             } 
449+         } 
450+         DataType :: Int64  => { 
451+             let  array = array. as_any ( ) . downcast_ref :: < Int64Array > ( ) . unwrap ( ) ; 
452+             if  scalar. is_null ( )  { 
453+                 Ok ( new_null_array ( array. data_type ( ) ,  len) ) 
454+             }  else  { 
455+                 let  right:  i64  = scalar. try_into ( ) . unwrap ( ) ; 
456+                 let  result = ( 0 ..len) 
457+                     . into_iter ( ) 
458+                     . map ( |i| Some ( array. value ( i)  &  right) ) 
459+                     . collect :: < Int64Array > ( ) ; 
460+                 Ok ( Arc :: new ( result)  as  ArrayRef ) 
461+             } 
462+         } 
463+         other => Err ( DataFusionError :: Internal ( format ! ( 
464+             "Data type {:?} not supported for binary operation '{}' on dyn arrays" , 
465+             other, 
466+             Operator :: BitwiseAnd 
467+         ) ) ) , 
468+     } ; 
469+     Some ( result) 
470+ } 
471+ 
337472/// Binary expression 
338473#[ derive( Debug ) ]  
339474pub  struct  BinaryExpr  { 
@@ -564,6 +699,14 @@ macro_rules! binary_primitive_array_op {
564699    } } ; 
565700} 
566701
702+ /// The binary_bitwise_array_op macro only evaluates for integer types 
703+ /// like int64, int32 
704+ // macro_rules! binary_bitwise_array_op { 
705+ //     ($LEFT:expr, $RIGHT: expr, $OP:ident) => {{ 
706+ // 
707+ //     }}; 
708+ // } 
709+ 
567710/// Invoke a compute kernel on an array and a scalar 
568711/// The binary_primitive_array_op_scalar macro only evaluates for primitive 
569712/// types like integers and floats. 
@@ -811,6 +954,8 @@ pub fn binary_operator_data_type(
811954        | Operator :: RegexNotIMatch 
812955        | Operator :: IsDistinctFrom 
813956        | Operator :: IsNotDistinctFrom  => Ok ( DataType :: Boolean ) , 
957+         // bitwise operations return the common coerced type 
958+         Operator :: BitwiseAnd  => Ok ( result_type) , 
814959        // math operations return the same value as the common coerced type 
815960        Operator :: Plus 
816961        | Operator :: Minus 
@@ -939,6 +1084,7 @@ impl BinaryExpr {
9391084                true , 
9401085                true 
9411086            ) , 
1087+             Operator :: BitwiseAnd  => bitwise_and_scalar ( array,  scalar. clone ( ) ) , 
9421088            // if scalar operation is not supported - fallback to array implementation 
9431089            _ => None , 
9441090        } ; 
@@ -1027,6 +1173,7 @@ impl BinaryExpr {
10271173            Operator :: RegexNotIMatch  => { 
10281174                binary_string_array_flag_op ! ( left,  right,  regexp_is_match,  true ,  true ) 
10291175            } 
1176+             Operator :: BitwiseAnd  => bitwise_and ( left,  right) , 
10301177        } 
10311178    } 
10321179} 
0 commit comments