You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by tu...@apache.org on 2022/11/28 13:18:25 UTC

[arrow-rs] branch master updated: fix bug: cast decimal256 to other decimal with safe(false) (#3208)

This is an automated email from the ASF dual-hosted git repository.

tustvold pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/master by this push:
     new 6f41b95de fix bug: cast decimal256 to other decimal with safe(false) (#3208)
6f41b95de is described below

commit 6f41b95de4a0ac33319b9e96e179b47fcd71fdbf
Author: Kun Liu <li...@apache.org>
AuthorDate: Mon Nov 28 21:18:20 2022 +0800

    fix bug: cast decimal256 to other decimal with safe(false) (#3208)
---
 arrow-cast/src/cast.rs | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/arrow-cast/src/cast.rs b/arrow-cast/src/cast.rs
index 1f5359bae..aa40ad425 100644
--- a/arrow-cast/src/cast.rs
+++ b/arrow-cast/src/cast.rs
@@ -2128,8 +2128,8 @@ fn cast_decimal_to_decimal<const BYTE_WIDTH1: usize, const BYTE_WIDTH2: usize>(
     if input_scale > output_scale {
         // For example, input_scale is 4 and output_scale is 3;
         // Original value is 11234_i128, and will be cast to 1123_i128.
-        let array = array.as_any().downcast_ref::<Decimal128Array>().unwrap();
         if BYTE_WIDTH1 == 16 {
+            let array = array.as_any().downcast_ref::<Decimal128Array>().unwrap();
             if BYTE_WIDTH2 == 16 {
                 let div = 10_i128
                     .pow_checked((input_scale - output_scale) as u32)
@@ -3816,6 +3816,34 @@ mod tests {
         );
     }
 
+    #[test]
+    fn test_cast_decimal256_to_decimal128_overflow() {
+        let input_type = DataType::Decimal256(76, 5);
+        let output_type = DataType::Decimal128(38, 7);
+        assert!(can_cast_types(&input_type, &output_type));
+        let array = vec![Some(i256::from_i128(i128::MAX))];
+        let input_decimal_array = create_decimal256_array(array, 76, 5).unwrap();
+        let array = Arc::new(input_decimal_array) as ArrayRef;
+        let result =
+            cast_with_options(&array, &output_type, &CastOptions { safe: false });
+        assert_eq!("Invalid argument error: 17014118346046923173168730371588410572700 cannot be casted to 128-bit integer for Decimal128",
+                   result.unwrap_err().to_string());
+    }
+
+    #[test]
+    fn test_cast_decimal256_to_decimal256_overflow() {
+        let input_type = DataType::Decimal256(76, 5);
+        let output_type = DataType::Decimal256(76, 55);
+        assert!(can_cast_types(&input_type, &output_type));
+        let array = vec![Some(i256::from_i128(i128::MAX))];
+        let input_decimal_array = create_decimal256_array(array, 76, 5).unwrap();
+        let array = Arc::new(input_decimal_array) as ArrayRef;
+        let result =
+            cast_with_options(&array, &output_type, &CastOptions { safe: false });
+        assert_eq!("Cast error: Cannot cast to \"Decimal256\"(76, 55). Overflowing on 170141183460469231731687303715884105727",
+                   result.unwrap_err().to_string());
+    }
+
     #[test]
     fn test_cast_decimal256_to_decimal128() {
         let input_type = DataType::Decimal256(20, 3);