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]