diff --git a/arrow-cast/src/cast/decimal.rs b/arrow-cast/src/cast/decimal.rs index 00bfc57e127c..095e31274887 100644 --- a/arrow-cast/src/cast/decimal.rs +++ b/arrow-cast/src/cast/decimal.rs @@ -81,7 +81,9 @@ impl DecimalCast for i64 { } fn from_f64(n: f64) -> Option { - n.to_i64() + // Call implementation explicitly otherwise this resolves to `to_i64` + // in arrow-buffer that behaves differently. + num::traits::ToPrimitive::to_i64(&n) } } diff --git a/arrow-cast/src/cast/mod.rs b/arrow-cast/src/cast/mod.rs index 117ad10b116d..fc241bea48da 100644 --- a/arrow-cast/src/cast/mod.rs +++ b/arrow-cast/src/cast/mod.rs @@ -3101,6 +3101,35 @@ mod tests { ); } + #[test] + fn test_cast_floating_to_decimals() { + for output_type in [ + DataType::Decimal32(9, 3), + DataType::Decimal64(9, 3), + DataType::Decimal128(9, 3), + DataType::Decimal256(9, 3), + ] { + let input_type = DataType::Float64; + assert!(can_cast_types(&input_type, &output_type)); + + let array = vec![Some(1.1_f64)]; + let array = PrimitiveArray::::from_iter(array); + let result = cast_with_options( + &array, + &output_type, + &CastOptions { + safe: false, + format_options: FormatOptions::default(), + }, + ); + assert!( + result.is_ok(), + "Failed to cast to {output_type} with: {}", + result.unwrap_err() + ); + } + } + #[test] fn test_cast_decimal128_to_decimal128_overflow() { let input_type = DataType::Decimal128(38, 3); diff --git a/parquet-testing b/parquet-testing index 5cbfc43d488c..a3d96a65e11e 160000 --- a/parquet-testing +++ b/parquet-testing @@ -1 +1 @@ -Subproject commit 5cbfc43d488c9c8404a1a7088cca400ae095b831 +Subproject commit a3d96a65e11e2bbca7d22a894e8313ede90a33a3