@@ -348,6 +348,103 @@ fn modulus_decimal(left: &DecimalArray, right: &DecimalArray) -> Result<DecimalA
348348    Ok ( decimal_builder. finish ( ) ) 
349349} 
350350
351+ /// The binary_bitwise_array_op macro only evaluates for integer types 
352+ /// like int64, int32. 
353+ /// It is used to do bitwise operation. 
354+ macro_rules!  binary_bitwise_array_op { 
355+     ( $LEFT: expr,  $RIGHT: expr,  $OP: tt,  $ARRAY_TYPE: ident,  $TYPE: ty)  => { { 
356+         let  len = $LEFT. len( ) ; 
357+         let  left = $LEFT. as_any( ) . downcast_ref:: <$ARRAY_TYPE>( ) . unwrap( ) ; 
358+         let  right = $RIGHT. as_any( ) . downcast_ref:: <$ARRAY_TYPE>( ) . unwrap( ) ; 
359+         let  result = ( 0 ..len) 
360+             . into_iter( ) 
361+             . map( |i| { 
362+                 if  left. is_null( i)  || right. is_null( i)  { 
363+                     None 
364+                 }  else { 
365+                     Some ( left. value( i)  $OP right. value( i) ) 
366+                 } 
367+             } ) 
368+             . collect:: <$ARRAY_TYPE>( ) ; 
369+         Ok ( Arc :: new( result) ) 
370+     } } ; 
371+ } 
372+ 
373+ /// The binary_bitwise_array_op macro only evaluates for integer types 
374+ /// like int64, int32. 
375+ /// It is used to do bitwise operation on an array with a scalar. 
376+ macro_rules!  binary_bitwise_array_scalar { 
377+     ( $LEFT: expr,  $RIGHT: expr,  $OP: tt,  $ARRAY_TYPE: ident,  $TYPE: ty)  => { { 
378+         let  len = $LEFT. len( ) ; 
379+         let  array = $LEFT. as_any( ) . downcast_ref:: <$ARRAY_TYPE>( ) . unwrap( ) ; 
380+         let  scalar = $RIGHT; 
381+         if  scalar. is_null( )  { 
382+             Ok ( new_null_array( array. data_type( ) ,  len) ) 
383+         }  else { 
384+             let  right:  $TYPE = scalar. try_into( ) . unwrap( ) ; 
385+             let  result = ( 0 ..len) 
386+                 . into_iter( ) 
387+                 . map( |i| { 
388+                     if  array. is_null( i)  { 
389+                         None 
390+                     }  else { 
391+                         Some ( array. value( i)  $OP right) 
392+                     } 
393+                 } ) 
394+                 . collect:: <$ARRAY_TYPE>( ) ; 
395+             Ok ( Arc :: new( result)  as  ArrayRef ) 
396+         } 
397+     } } ; 
398+ } 
399+ 
400+ fn  bitwise_and ( left :  ArrayRef ,  right :  ArrayRef )  -> Result < ArrayRef >  { 
401+     match  & left. data_type ( )  { 
402+         DataType :: Int8  => { 
403+             binary_bitwise_array_op ! ( left,  right,  & ,  Int8Array ,  i8 ) 
404+         } 
405+         DataType :: Int16  => { 
406+             binary_bitwise_array_op ! ( left,  right,  & ,  Int16Array ,  i16 ) 
407+         } 
408+         DataType :: Int32  => { 
409+             binary_bitwise_array_op ! ( left,  right,  & ,  Int32Array ,  i32 ) 
410+         } 
411+         DataType :: Int64  => { 
412+             binary_bitwise_array_op ! ( left,  right,  & ,  Int64Array ,  i64 ) 
413+         } 
414+         other => Err ( DataFusionError :: Internal ( format ! ( 
415+             "Data type {:?} not supported for binary operation '{}' on dyn arrays" , 
416+             other, 
417+             Operator :: BitwiseAnd 
418+         ) ) ) , 
419+     } 
420+ } 
421+ 
422+ fn  bitwise_and_scalar ( 
423+     array :  & dyn  Array , 
424+     scalar :  ScalarValue , 
425+ )  -> Option < Result < ArrayRef > >  { 
426+     let  result = match  array. data_type ( )  { 
427+         DataType :: Int8  => { 
428+             binary_bitwise_array_scalar ! ( array,  scalar,  & ,  Int8Array ,  i8 ) 
429+         } 
430+         DataType :: Int16  => { 
431+             binary_bitwise_array_scalar ! ( array,  scalar,  & ,  Int16Array ,  i16 ) 
432+         } 
433+         DataType :: Int32  => { 
434+             binary_bitwise_array_scalar ! ( array,  scalar,  & ,  Int32Array ,  i32 ) 
435+         } 
436+         DataType :: Int64  => { 
437+             binary_bitwise_array_scalar ! ( array,  scalar,  & ,  Int64Array ,  i64 ) 
438+         } 
439+         other => Err ( DataFusionError :: Internal ( format ! ( 
440+             "Data type {:?} not supported for binary operation '{}' on dyn arrays" , 
441+             other, 
442+             Operator :: BitwiseAnd 
443+         ) ) ) , 
444+     } ; 
445+     Some ( result) 
446+ } 
447+ 
351448/// Binary expression 
352449#[ derive( Debug ) ]  
353450pub  struct  BinaryExpr  { 
@@ -880,6 +977,8 @@ pub fn binary_operator_data_type(
880977        | Operator :: RegexNotIMatch 
881978        | Operator :: IsDistinctFrom 
882979        | Operator :: IsNotDistinctFrom  => Ok ( DataType :: Boolean ) , 
980+         // bitwise operations return the common coerced type 
981+         Operator :: BitwiseAnd  => Ok ( result_type) , 
883982        // math operations return the same value as the common coerced type 
884983        Operator :: Plus 
885984        | Operator :: Minus 
@@ -1055,6 +1154,7 @@ impl BinaryExpr {
10551154                true , 
10561155                true 
10571156            ) , 
1157+             Operator :: BitwiseAnd  => bitwise_and_scalar ( array,  scalar. clone ( ) ) , 
10581158            // if scalar operation is not supported - fallback to array implementation 
10591159            _ => None , 
10601160        } ; 
@@ -1143,6 +1243,7 @@ impl BinaryExpr {
11431243            Operator :: RegexNotIMatch  => { 
11441244                binary_string_array_flag_op ! ( left,  right,  regexp_is_match,  true ,  true ) 
11451245            } 
1246+             Operator :: BitwiseAnd  => bitwise_and ( left,  right) , 
11461247        } 
11471248    } 
11481249} 
@@ -1580,6 +1681,18 @@ mod tests {
15801681            DataType :: Boolean , 
15811682            vec![ false ,  false ,  false ,  false ,  true ] 
15821683        ) ; 
1684+         test_coercion ! ( 
1685+             Int16Array , 
1686+             DataType :: Int16 , 
1687+             vec![ 1i16 ,  2i16 ,  3i16 ] , 
1688+             Int64Array , 
1689+             DataType :: Int64 , 
1690+             vec![ 10i64 ,  4i64 ,  5i64 ] , 
1691+             Operator :: BitwiseAnd , 
1692+             Int64Array , 
1693+             DataType :: Int64 , 
1694+             vec![ 0i64 ,  0i64 ,  1i64 ] 
1695+         ) ; 
15831696        Ok ( ( ) ) 
15841697    } 
15851698
@@ -2954,4 +3067,25 @@ mod tests {
29543067
29553068        Ok ( ( ) ) 
29563069    } 
3070+ 
3071+     #[ test]  
3072+     fn  bitwise_array_test ( )  -> Result < ( ) >  { 
3073+         let  left = Arc :: new ( Int32Array :: from ( vec ! [ Some ( 12 ) ,  None ,  Some ( 11 ) ] ) )  as  ArrayRef ; 
3074+         let  right =
3075+             Arc :: new ( Int32Array :: from ( vec ! [ Some ( 1 ) ,  Some ( 3 ) ,  Some ( 7 ) ] ) )  as  ArrayRef ; 
3076+         let  result = bitwise_and ( left,  right) ?; 
3077+         let  expected = Int32Array :: from ( vec ! [ Some ( 0 ) ,  None ,  Some ( 3 ) ] ) ; 
3078+         assert_eq ! ( result. as_ref( ) ,  & expected) ; 
3079+         Ok ( ( ) ) 
3080+     } 
3081+ 
3082+     #[ test]  
3083+     fn  bitwise_scalar_test ( )  -> Result < ( ) >  { 
3084+         let  left = Arc :: new ( Int32Array :: from ( vec ! [ Some ( 12 ) ,  None ,  Some ( 11 ) ] ) )  as  ArrayRef ; 
3085+         let  right = ScalarValue :: from ( 3i32 ) ; 
3086+         let  result = bitwise_and_scalar ( & left,  right) . unwrap ( ) ?; 
3087+         let  expected = Int32Array :: from ( vec ! [ Some ( 0 ) ,  None ,  Some ( 3 ) ] ) ; 
3088+         assert_eq ! ( result. as_ref( ) ,  & expected) ; 
3089+         Ok ( ( ) ) 
3090+     } 
29573091} 
0 commit comments