@@ -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