alamb commented on code in PR #3281:
URL: https://github.com/apache/arrow-rs/pull/3281#discussion_r1044747937


##########
arrow-cast/src/cast.rs:
##########
@@ -7104,4 +7300,256 @@ mod tests {
             ]
         );
     }
+
+    #[test]
+    fn test_parse_string_to_decimal() {
+        assert_eq!(
+            Decimal128Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal128Type>("123.45", 
2).unwrap(),
+                38,
+                2,
+            ),
+            "123.45"
+        );
+        assert_eq!(
+            Decimal128Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal128Type>("12345", 
2).unwrap(),
+                38,
+                2
+            ),
+            "12345.00"
+        );
+        assert_eq!(
+            Decimal128Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal128Type>("0.12345", 
2).unwrap(),

Review Comment:
   I recommend test coverage for the following cases (apologies if they are 
already covered but I didn't see them):
   
   1. trim, eg, `". 0.123"`
   2. Multiple leading zeros: `"000.123"`
   3. Multiple trailing zeros: `"12.234000"`
   4. empty string `""`
   4. whitespace string `"   "`
   5. Invalid `"4.4.5"`



##########
arrow-cast/src/cast.rs:
##########
@@ -7104,4 +7300,256 @@ mod tests {
             ]
         );
     }
+
+    #[test]
+    fn test_parse_string_to_decimal() {
+        assert_eq!(
+            Decimal128Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal128Type>("123.45", 
2).unwrap(),
+                38,
+                2,
+            ),
+            "123.45"
+        );
+        assert_eq!(
+            Decimal128Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal128Type>("12345", 
2).unwrap(),
+                38,
+                2
+            ),
+            "12345.00"
+        );
+        assert_eq!(
+            Decimal128Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal128Type>("0.12345", 
2).unwrap(),
+                38,
+                2
+            ),
+            "0.12"
+        );
+        assert_eq!(
+            Decimal128Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal128Type>(".12345", 
2).unwrap(),
+                38,
+                2
+            ),
+            "0.12"
+        );
+        assert_eq!(
+            Decimal128Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal128Type>(".1265", 
2).unwrap(),
+                38,
+                2
+            ),
+            "0.13"
+        );
+        assert_eq!(
+            Decimal128Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal128Type>(".1265", 
2).unwrap(),
+                38,
+                2
+            ),
+            "0.13"
+        );
+
+        assert_eq!(
+            Decimal256Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal256Type>("123.45", 
3).unwrap(),
+                38,
+                3
+            ),
+            "123.450"
+        );
+        assert_eq!(
+            Decimal256Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal256Type>("12345", 
3).unwrap(),
+                38,
+                3
+            ),
+            "12345.000"
+        );
+        assert_eq!(
+            Decimal256Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal256Type>("0.12345", 
3).unwrap(),
+                38,
+                3
+            ),
+            "0.123"
+        );
+        assert_eq!(
+            Decimal256Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal256Type>(".12345", 
3).unwrap(),
+                38,
+                3
+            ),
+            "0.123"
+        );
+        assert_eq!(
+            Decimal256Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal256Type>(".1265", 
3).unwrap(),
+                38,
+                3
+            ),
+            "0.127"
+        );
+    }
+
+    fn test_cast_string_to_decimal(array: ArrayRef) {
+        // Decimal128
+        let output_type = DataType::Decimal128(38, 2);
+        assert!(can_cast_types(array.data_type(), &output_type));
+
+        let casted_array = cast(&array, &output_type).unwrap();
+        let decimal_arr = as_primitive_array::<Decimal128Type>(&casted_array);
+
+        assert_eq!("123.45", decimal_arr.value_as_string(0));
+        assert_eq!("1.23", decimal_arr.value_as_string(1));
+        assert_eq!("0.12", decimal_arr.value_as_string(2));
+        assert_eq!("0.13", decimal_arr.value_as_string(3));
+        assert_eq!("1.26", decimal_arr.value_as_string(4));
+        assert_eq!("12345.00", decimal_arr.value_as_string(5));
+        assert_eq!("12345.00", decimal_arr.value_as_string(6));
+
+        // Decimal256
+        let output_type = DataType::Decimal256(76, 3);
+        assert!(can_cast_types(array.data_type(), &output_type));
+
+        let casted_array = cast(&array, &output_type).unwrap();
+        let decimal_arr = as_primitive_array::<Decimal256Type>(&casted_array);
+
+        assert_eq!("123.450", decimal_arr.value_as_string(0));
+        assert_eq!("1.235", decimal_arr.value_as_string(1));
+        assert_eq!("0.123", decimal_arr.value_as_string(2));
+        assert_eq!("0.127", decimal_arr.value_as_string(3));
+        assert_eq!("1.263", decimal_arr.value_as_string(4));
+        assert_eq!("12345.000", decimal_arr.value_as_string(5));
+        assert_eq!("12345.000", decimal_arr.value_as_string(6));
+    }
+
+    #[test]
+    fn test_cast_utf8_to_decimal() {
+        let str_array = StringArray::from(vec![
+            "123.45", "1.2345", "0.12345", "0.1267", "1.263", "12345.0", 
"12345",
+        ]);
+        let array = Arc::new(str_array) as ArrayRef;
+
+        test_cast_string_to_decimal(array);
+    }
+
+    #[test]
+    fn test_cast_large_utf8_to_decimal() {
+        let str_array = LargeStringArray::from(vec![
+            "123.45", "1.2345", "0.12345", "0.1267", "1.263", "12345.0", 
"12345",

Review Comment:
   I recommend a test for an input array that has Nulls in it as well 



##########
arrow-cast/src/cast.rs:
##########
@@ -7104,4 +7300,256 @@ mod tests {
             ]
         );
     }
+
+    #[test]
+    fn test_parse_string_to_decimal() {
+        assert_eq!(
+            Decimal128Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal128Type>("123.45", 
2).unwrap(),
+                38,
+                2,
+            ),
+            "123.45"
+        );
+        assert_eq!(
+            Decimal128Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal128Type>("12345", 
2).unwrap(),
+                38,
+                2
+            ),
+            "12345.00"
+        );
+        assert_eq!(
+            Decimal128Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal128Type>("0.12345", 
2).unwrap(),
+                38,
+                2
+            ),
+            "0.12"
+        );
+        assert_eq!(
+            Decimal128Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal128Type>(".12345", 
2).unwrap(),
+                38,
+                2
+            ),
+            "0.12"
+        );
+        assert_eq!(
+            Decimal128Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal128Type>(".1265", 
2).unwrap(),
+                38,
+                2
+            ),
+            "0.13"
+        );
+        assert_eq!(
+            Decimal128Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal128Type>(".1265", 
2).unwrap(),
+                38,
+                2
+            ),
+            "0.13"
+        );
+
+        assert_eq!(
+            Decimal256Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal256Type>("123.45", 
3).unwrap(),
+                38,
+                3
+            ),
+            "123.450"
+        );
+        assert_eq!(
+            Decimal256Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal256Type>("12345", 
3).unwrap(),
+                38,
+                3
+            ),
+            "12345.000"
+        );
+        assert_eq!(
+            Decimal256Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal256Type>("0.12345", 
3).unwrap(),
+                38,
+                3
+            ),
+            "0.123"
+        );
+        assert_eq!(
+            Decimal256Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal256Type>(".12345", 
3).unwrap(),
+                38,
+                3
+            ),
+            "0.123"
+        );
+        assert_eq!(
+            Decimal256Type::format_decimal(
+                parse_string_to_decimal_native::<Decimal256Type>(".1265", 
3).unwrap(),
+                38,
+                3
+            ),
+            "0.127"
+        );
+    }
+
+    fn test_cast_string_to_decimal(array: ArrayRef) {
+        // Decimal128
+        let output_type = DataType::Decimal128(38, 2);
+        assert!(can_cast_types(array.data_type(), &output_type));
+
+        let casted_array = cast(&array, &output_type).unwrap();
+        let decimal_arr = as_primitive_array::<Decimal128Type>(&casted_array);
+
+        assert_eq!("123.45", decimal_arr.value_as_string(0));
+        assert_eq!("1.23", decimal_arr.value_as_string(1));
+        assert_eq!("0.12", decimal_arr.value_as_string(2));
+        assert_eq!("0.13", decimal_arr.value_as_string(3));
+        assert_eq!("1.26", decimal_arr.value_as_string(4));
+        assert_eq!("12345.00", decimal_arr.value_as_string(5));
+        assert_eq!("12345.00", decimal_arr.value_as_string(6));
+
+        // Decimal256
+        let output_type = DataType::Decimal256(76, 3);
+        assert!(can_cast_types(array.data_type(), &output_type));
+
+        let casted_array = cast(&array, &output_type).unwrap();
+        let decimal_arr = as_primitive_array::<Decimal256Type>(&casted_array);
+
+        assert_eq!("123.450", decimal_arr.value_as_string(0));
+        assert_eq!("1.235", decimal_arr.value_as_string(1));
+        assert_eq!("0.123", decimal_arr.value_as_string(2));
+        assert_eq!("0.127", decimal_arr.value_as_string(3));
+        assert_eq!("1.263", decimal_arr.value_as_string(4));
+        assert_eq!("12345.000", decimal_arr.value_as_string(5));
+        assert_eq!("12345.000", decimal_arr.value_as_string(6));
+    }
+
+    #[test]
+    fn test_cast_utf8_to_decimal() {
+        let str_array = StringArray::from(vec![
+            "123.45", "1.2345", "0.12345", "0.1267", "1.263", "12345.0", 
"12345",
+        ]);
+        let array = Arc::new(str_array) as ArrayRef;
+
+        test_cast_string_to_decimal(array);
+    }
+
+    #[test]
+    fn test_cast_large_utf8_to_decimal() {
+        let str_array = LargeStringArray::from(vec![
+            "123.45", "1.2345", "0.12345", "0.1267", "1.263", "12345.0", 
"12345",
+        ]);
+        let array = Arc::new(str_array) as ArrayRef;
+
+        test_cast_string_to_decimal(array);
+    }
+
+    fn test_cast_string_to_decimal128_overflow(overflow_array: ArrayRef) {
+        let output_type = DataType::Decimal128(38, 2);
+        let casted_array = cast(&overflow_array, &output_type).unwrap();
+        let decimal_arr = as_primitive_array::<Decimal128Type>(&casted_array);
+
+        assert!(decimal_arr.is_null(0));
+        assert!(decimal_arr.is_null(1));
+        assert!(decimal_arr.is_null(2));
+        assert_eq!(
+            "999999999999999999999999999999999999.99",
+            decimal_arr.value_as_string(3)
+        );
+        assert_eq!(
+            "100000000000000000000000000000000000.00",
+            decimal_arr.value_as_string(4)
+        );
+    }
+
+    #[test]
+    fn test_cast_utf8_to_decimal128_overflow() {

Review Comment:
   👍 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to