@@ -824,18 +824,20 @@ pub fn cast_with_options(
824
824
( Map ( _, ordered1) , Map ( _, ordered2) ) if ordered1 == ordered2 => {
825
825
cast_map_values ( array. as_map ( ) , to_type, cast_options, ordered1. to_owned ( ) )
826
826
}
827
- ( Decimal128 ( _ , s1) , Decimal128 ( p2, s2) ) => {
827
+ ( Decimal128 ( p1 , s1) , Decimal128 ( p2, s2) ) => {
828
828
cast_decimal_to_decimal_same_type :: < Decimal128Type > (
829
829
array. as_primitive ( ) ,
830
+ * p1,
830
831
* s1,
831
832
* p2,
832
833
* s2,
833
834
cast_options,
834
835
)
835
836
}
836
- ( Decimal256 ( _ , s1) , Decimal256 ( p2, s2) ) => {
837
+ ( Decimal256 ( p1 , s1) , Decimal256 ( p2, s2) ) => {
837
838
cast_decimal_to_decimal_same_type :: < Decimal256Type > (
838
839
array. as_primitive ( ) ,
840
+ * p1,
839
841
* s1,
840
842
* p2,
841
843
* s2,
@@ -2681,13 +2683,16 @@ mod tests {
2681
2683
// negative test
2682
2684
let array = vec ! [ Some ( 123456 ) , None ] ;
2683
2685
let array = create_decimal_array ( array, 10 , 0 ) . unwrap ( ) ;
2684
- let result = cast ( & array, & DataType :: Decimal128 ( 2 , 2 ) ) ;
2685
- assert ! ( result. is_ok( ) ) ;
2686
- let array = result. unwrap ( ) ;
2687
- let array: & Decimal128Array = array. as_primitive ( ) ;
2688
- let err = array. validate_decimal_precision ( 2 ) ;
2686
+ let result_safe = cast ( & array, & DataType :: Decimal128 ( 2 , 2 ) ) ;
2687
+ assert ! ( result_safe. is_ok( ) ) ;
2688
+ let options = CastOptions {
2689
+ safe : false ,
2690
+ ..Default :: default ( )
2691
+ } ;
2692
+
2693
+ let result_unsafe = cast_with_options ( & array, & DataType :: Decimal128 ( 2 , 2 ) , & options) ;
2689
2694
assert_eq ! ( "Invalid argument error: 12345600 is too large to store in a Decimal128 of precision 2. Max is 99" ,
2690
- err . unwrap_err( ) . to_string( ) ) ;
2695
+ result_unsafe . unwrap_err( ) . to_string( ) ) ;
2691
2696
}
2692
2697
2693
2698
#[ test]
@@ -8388,7 +8393,7 @@ mod tests {
8388
8393
let input_type = DataType :: Decimal128 ( 10 , 3 ) ;
8389
8394
let output_type = DataType :: Decimal256 ( 10 , 5 ) ;
8390
8395
assert ! ( can_cast_types( & input_type, & output_type) ) ;
8391
- let array = vec ! [ Some ( i128 :: MAX ) , Some ( i128 :: MIN ) ] ;
8396
+ let array = vec ! [ Some ( 123456 ) , Some ( - 123456 ) ] ;
8392
8397
let input_decimal_array = create_decimal_array ( array, 10 , 3 ) . unwrap ( ) ;
8393
8398
let array = Arc :: new ( input_decimal_array) as ArrayRef ;
8394
8399
@@ -8398,8 +8403,8 @@ mod tests {
8398
8403
Decimal256Array ,
8399
8404
& output_type,
8400
8405
vec![
8401
- Some ( i256:: from_i128( i128 :: MAX ) . mul_wrapping( hundred) ) ,
8402
- Some ( i256:: from_i128( i128 :: MIN ) . mul_wrapping( hundred) )
8406
+ Some ( i256:: from_i128( 123456 ) . mul_wrapping( hundred) ) ,
8407
+ Some ( i256:: from_i128( - 123456 ) . mul_wrapping( hundred) )
8403
8408
]
8404
8409
) ;
8405
8410
}
@@ -9827,4 +9832,76 @@ mod tests {
9827
9832
"Cast non-nullable to non-nullable struct field returning null should fail" ,
9828
9833
) ;
9829
9834
}
9835
+
9836
+ #[ test]
9837
+ fn test_decimal_to_decimal_throw_error_on_precision_overflow_same_scale ( ) {
9838
+ let array = vec ! [ Some ( 123456789 ) ] ;
9839
+ let array = create_decimal_array ( array, 24 , 2 ) . unwrap ( ) ;
9840
+ println ! ( "{:?}" , array) ;
9841
+ let input_type = DataType :: Decimal128 ( 24 , 2 ) ;
9842
+ let output_type = DataType :: Decimal128 ( 6 , 2 ) ;
9843
+ assert ! ( can_cast_types( & input_type, & output_type) ) ;
9844
+
9845
+ let options = CastOptions {
9846
+ safe : false ,
9847
+ ..Default :: default ( )
9848
+ } ;
9849
+ let result = cast_with_options ( & array, & output_type, & options) ;
9850
+ assert_eq ! ( result. unwrap_err( ) . to_string( ) ,
9851
+ "Invalid argument error: 123456790 is too large to store in a Decimal128 of precision 6. Max is 999999" ) ;
9852
+ }
9853
+
9854
+ #[ test]
9855
+ fn test_decimal_to_decimal_throw_error_on_precision_overflow_lower_scale ( ) {
9856
+ let array = vec ! [ Some ( 123456789 ) ] ;
9857
+ let array = create_decimal_array ( array, 24 , 2 ) . unwrap ( ) ;
9858
+ println ! ( "{:?}" , array) ;
9859
+ let input_type = DataType :: Decimal128 ( 24 , 4 ) ;
9860
+ let output_type = DataType :: Decimal128 ( 6 , 2 ) ;
9861
+ assert ! ( can_cast_types( & input_type, & output_type) ) ;
9862
+
9863
+ let options = CastOptions {
9864
+ safe : false ,
9865
+ ..Default :: default ( )
9866
+ } ;
9867
+ let result = cast_with_options ( & array, & output_type, & options) ;
9868
+ assert_eq ! ( result. unwrap_err( ) . to_string( ) ,
9869
+ "Invalid argument error: 123456790 is too large to store in a Decimal128 of precision 6. Max is 999999" ) ;
9870
+ }
9871
+
9872
+ #[ test]
9873
+ fn test_decimal_to_decimal_throw_error_on_precision_overflow_greater_scale ( ) {
9874
+ let array = vec ! [ Some ( 123456789 ) ] ;
9875
+ let array = create_decimal_array ( array, 24 , 2 ) . unwrap ( ) ;
9876
+ println ! ( "{:?}" , array) ;
9877
+ let input_type = DataType :: Decimal128 ( 24 , 2 ) ;
9878
+ let output_type = DataType :: Decimal128 ( 6 , 3 ) ;
9879
+ assert ! ( can_cast_types( & input_type, & output_type) ) ;
9880
+
9881
+ let options = CastOptions {
9882
+ safe : false ,
9883
+ ..Default :: default ( )
9884
+ } ;
9885
+ let result = cast_with_options ( & array, & output_type, & options) ;
9886
+ assert_eq ! ( result. unwrap_err( ) . to_string( ) ,
9887
+ "Invalid argument error: 1234567890 is too large to store in a Decimal128 of precision 6. Max is 999999" ) ;
9888
+ }
9889
+
9890
+ #[ test]
9891
+ fn test_decimal_to_decimal_throw_error_on_precision_overflow_diff_type ( ) {
9892
+ let array = vec ! [ Some ( 123456789 ) ] ;
9893
+ let array = create_decimal_array ( array, 24 , 2 ) . unwrap ( ) ;
9894
+ println ! ( "{:?}" , array) ;
9895
+ let input_type = DataType :: Decimal128 ( 24 , 2 ) ;
9896
+ let output_type = DataType :: Decimal256 ( 6 , 2 ) ;
9897
+ assert ! ( can_cast_types( & input_type, & output_type) ) ;
9898
+
9899
+ let options = CastOptions {
9900
+ safe : false ,
9901
+ ..Default :: default ( )
9902
+ } ;
9903
+ let result = cast_with_options ( & array, & output_type, & options) ;
9904
+ assert_eq ! ( result. unwrap_err( ) . to_string( ) ,
9905
+ "Invalid argument error: 123456789 is too large to store in a Decimal256 of precision 6. Max is 999999" ) ;
9906
+ }
9830
9907
}
0 commit comments