@@ -20,6 +20,7 @@ use std::{any::Any, convert::TryInto, sync::Arc};
2020use  crate :: record_batch:: RecordBatch ; 
2121use  arrow:: array:: * ; 
2222use  arrow:: compute; 
23+ use  arrow:: datatypes:: DataType :: Decimal ; 
2324use  arrow:: datatypes:: { DataType ,  Schema } ; 
2425
2526use  crate :: error:: { DataFusionError ,  Result } ; 
@@ -247,9 +248,24 @@ fn evaluate_regex_case_insensitive<O: Offset>(
247248
248249fn  evaluate ( lhs :  & dyn  Array ,  op :  & Operator ,  rhs :  & dyn  Array )  -> Result < Arc < dyn  Array > >  { 
249250    use  Operator :: * ; 
250-     if  matches ! ( op,  Plus  | Minus  | Divide  | Multiply  | Modulo  | BitwiseAnd )  { 
251+     if  matches ! ( op,  Plus )  { 
252+         let  arr:  ArrayRef  = match  ( lhs. data_type ( ) ,  rhs. data_type ( ) )  { 
253+             ( Decimal ( p1,  s1) ,  Decimal ( p2,  s2) )  => { 
254+                 let  left_array =
255+                     lhs. as_any ( ) . downcast_ref :: < PrimitiveArray < i128 > > ( ) . unwrap ( ) ; 
256+                 let  right_array =
257+                     rhs. as_any ( ) . downcast_ref :: < PrimitiveArray < i128 > > ( ) . unwrap ( ) ; 
258+                 Arc :: new ( if  * p1 == * p2 && * s1 == * s2 { 
259+                     compute:: arithmetics:: decimal:: add ( left_array,  right_array) 
260+                 }  else  { 
261+                     compute:: arithmetics:: decimal:: adaptive_add ( left_array,  right_array) ?
262+                 } ) 
263+             } 
264+             _ => compute:: arithmetics:: add ( lhs,  rhs) . into ( ) , 
265+         } ; 
266+         Ok ( arr) 
267+     }  else  if  matches ! ( op,  Minus  | Divide  | Multiply  | Modulo )  { 
251268        let  arr = match  op { 
252-             Operator :: Plus  => compute:: arithmetics:: add ( lhs,  rhs) , 
253269            Operator :: Minus  => compute:: arithmetics:: sub ( lhs,  rhs) , 
254270            Operator :: Divide  => compute:: arithmetics:: div ( lhs,  rhs) , 
255271            Operator :: Multiply  => compute:: arithmetics:: mul ( lhs,  rhs) , 
@@ -828,6 +844,7 @@ mod tests {
828844    use  crate :: error:: Result ; 
829845    use  crate :: field_util:: SchemaExt ; 
830846    use  crate :: physical_plan:: expressions:: { col,  lit} ; 
847+     use  crate :: test_util:: create_decimal_array; 
831848    use  arrow:: datatypes:: { Field ,  SchemaRef } ; 
832849    use  arrow:: error:: ArrowError ; 
833850
@@ -1015,7 +1032,11 @@ mod tests {
10151032    } 
10161033
10171034    fn  add_decimal ( left :  & Int128Array ,  right :  & Int128Array )  -> Result < Int128Array >  { 
1018-         let  mut  decimal_builder = Int128Vec :: with_capacity ( left. len ( ) ) ; 
1035+         let  mut  decimal_builder = Int128Vec :: from_data ( 
1036+             left. data_type ( ) . clone ( ) , 
1037+             Vec :: < i128 > :: with_capacity ( left. len ( ) ) , 
1038+             None , 
1039+         ) ; 
10191040        for  i in  0 ..left. len ( )  { 
10201041            if  left. is_null ( i)  || right. is_null ( i)  { 
10211042                decimal_builder. push ( None ) ; 
@@ -1027,7 +1048,11 @@ mod tests {
10271048    } 
10281049
10291050    fn  subtract_decimal ( left :  & Int128Array ,  right :  & Int128Array )  -> Result < Int128Array >  { 
1030-         let  mut  decimal_builder = Int128Vec :: with_capacity ( left. len ( ) ) ; 
1051+         let  mut  decimal_builder = Int128Vec :: from_data ( 
1052+             left. data_type ( ) . clone ( ) , 
1053+             Vec :: < i128 > :: with_capacity ( left. len ( ) ) , 
1054+             None , 
1055+         ) ; 
10311056        for  i in  0 ..left. len ( )  { 
10321057            if  left. is_null ( i)  || right. is_null ( i)  { 
10331058                decimal_builder. push ( None ) ; 
@@ -1043,7 +1068,11 @@ mod tests {
10431068        right :  & Int128Array , 
10441069        scale :  u32 , 
10451070    )  -> Result < Int128Array >  { 
1046-         let  mut  decimal_builder = Int128Vec :: with_capacity ( left. len ( ) ) ; 
1071+         let  mut  decimal_builder = Int128Vec :: from_data ( 
1072+             left. data_type ( ) . clone ( ) , 
1073+             Vec :: < i128 > :: with_capacity ( left. len ( ) ) , 
1074+             None , 
1075+         ) ; 
10471076        let  divide = 10_i128 . pow ( scale) ; 
10481077        for  i in  0 ..left. len ( )  { 
10491078            if  left. is_null ( i)  || right. is_null ( i)  { 
@@ -1061,7 +1090,11 @@ mod tests {
10611090        right :  & Int128Array , 
10621091        scale :  i32 , 
10631092    )  -> Result < Int128Array >  { 
1064-         let  mut  decimal_builder = Int128Vec :: with_capacity ( left. len ( ) ) ; 
1093+         let  mut  decimal_builder = Int128Vec :: from_data ( 
1094+             left. data_type ( ) . clone ( ) , 
1095+             Vec :: < i128 > :: with_capacity ( left. len ( ) ) , 
1096+             None , 
1097+         ) ; 
10651098        let  mul = 10_f64 . powi ( scale) ; 
10661099        for  i in  0 ..left. len ( )  { 
10671100            if  left. is_null ( i)  || right. is_null ( i)  { 
@@ -1081,7 +1114,11 @@ mod tests {
10811114    } 
10821115
10831116    fn  modulus_decimal ( left :  & Int128Array ,  right :  & Int128Array )  -> Result < Int128Array >  { 
1084-         let  mut  decimal_builder = Int128Vec :: with_capacity ( left. len ( ) ) ; 
1117+         let  mut  decimal_builder = Int128Vec :: from_data ( 
1118+             left. data_type ( ) . clone ( ) , 
1119+             Vec :: < i128 > :: with_capacity ( left. len ( ) ) , 
1120+             None , 
1121+         ) ; 
10851122        for  i in  0 ..left. len ( )  { 
10861123            if  left. is_null ( i)  || right. is_null ( i)  { 
10871124                decimal_builder. push ( None ) ; 
@@ -2135,25 +2172,6 @@ mod tests {
21352172        assert_eq ! ( result. as_ref( ) ,  & expected as  & dyn Array ) ; 
21362173    } 
21372174
2138-     fn  create_decimal_array ( 
2139-         array :  & [ Option < i128 > ] , 
2140-         _precision :  usize , 
2141-         _scale :  usize , 
2142-     )  -> Result < Int128Array >  { 
2143-         let  mut  decimal_builder = Int128Vec :: with_capacity ( array. len ( ) ) ; 
2144-         for  value in  array { 
2145-             match  value { 
2146-                 None  => { 
2147-                     decimal_builder. push ( None ) ; 
2148-                 } 
2149-                 Some ( v)  => { 
2150-                     decimal_builder. try_push ( Some ( * v) ) ?; 
2151-                 } 
2152-             } 
2153-         } 
2154-         Ok ( decimal_builder. into ( ) ) 
2155-     } 
2156- 
21572175    #[ test]  
21582176    fn  comparison_decimal_op_test ( )  -> Result < ( ) >  { 
21592177        let  value_i128:  i128  = 123 ; 
0 commit comments