tustvold commented on code in PR #3021:
URL: https://github.com/apache/arrow-rs/pull/3021#discussion_r1014755155


##########
arrow-cast/src/cast.rs:
##########
@@ -344,16 +344,61 @@ fn cast_floating_point_to_decimal128<T: 
ArrowPrimitiveType>(
     array: &PrimitiveArray<T>,
     precision: u8,
     scale: u8,
+    cast_options: &CastOptions,
 ) -> Result<ArrayRef, ArrowError>
 where
     <T as ArrowPrimitiveType>::Native: AsPrimitive<f64>,
 {
     let mul = 10_f64.powi(scale as i32);
 
-    array
-        .unary::<_, Decimal128Type>(|v| (v.as_() * mul).round() as i128)
-        .with_precision_and_scale(precision, scale)
-        .map(|a| Arc::new(a) as ArrayRef)
+    if cast_options.safe {
+        let iter = array.iter().map(|v| {
+            v.and_then(|v| {
+                let mul_v = (mul * v.as_()).round();
+                if mul_v == f64::INFINITY || mul_v == f64::NEG_INFINITY {
+                    None
+                } else {
+                    Some(mul_v as i128)
+                }
+            })
+        });
+        let casted_array =
+            unsafe { 
PrimitiveArray::<Decimal128Type>::from_trusted_len_iter(iter) };
+        casted_array
+            .with_precision_and_scale(precision, scale)
+            .map(|a| Arc::new(a) as ArrayRef)
+    } else {
+        array
+            .try_unary::<_, Decimal128Type, _>(|v| {
+                mul.mul_checked(v.as_()).and_then(|value| {
+                    let mul_v = value.round();
+                    if mul_v == f64::INFINITY || mul_v == f64::NEG_INFINITY {
+                        Err(ArrowError::CastError(format!(
+                            "Cannot cast to {}({}, {}). Overflowing on {:?}",
+                            Decimal128Type::PREFIX,
+                            precision,
+                            scale,
+                            v
+                        )))
+                    } else {
+                        let integer = mul_v as i128;
+                        if integer == i128::MAX || integer == i128::MIN {

Review Comment:
   Oh... It seems support for this is unstable 
https://github.com/rust-lang/rust/issues/67057
   
   Perhaps we could use https://docs.rs/num/latest/num/trait.ToPrimitive.html ?
   
   This appears to be correctly checked 
https://docs.rs/num-traits/0.2.14/src/num_traits/cast.rs.html#310. We could 
also copy this logic



-- 
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