You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@arrow.apache.org by GitBox <gi...@apache.org> on 2022/07/26 15:20:14 UTC

[GitHub] [arrow-rs] tustvold commented on a diff in pull request #2169: Use ArrayAccessor and FromIterator in Cast Kernels

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


##########
arrow/src/compute/kernels/cast.rs:
##########
@@ -270,45 +269,62 @@ pub fn cast(array: &ArrayRef, to_type: &DataType) -> Result<ArrayRef> {
     cast_with_options(array, to_type, &DEFAULT_CAST_OPTIONS)
 }
 
-// cast the integer array to defined decimal data type array
-macro_rules! cast_integer_to_decimal {
-    ($ARRAY: expr, $ARRAY_TYPE: ident, $PRECISION : ident, $SCALE : ident) => {{
-        let array = $ARRAY.as_any().downcast_ref::<$ARRAY_TYPE>().unwrap();
-        let mul: i128 = 10_i128.pow(*$SCALE as u32);
-        let decimal_array = array
-            .iter()
-            .map(|v| {
-                v.map(|v| {
-                    let v = v as i128;
-                    // with_precision_and_scale validates the
-                    // value is within range for the output precision
-                    mul * v
-                })
-            })
-            .collect::<Decimal128Array>()
-            .with_precision_and_scale(*$PRECISION, *$SCALE)?;
-        Ok(Arc::new(decimal_array))
-    }};
+/// Cast the primitive array to defined decimal data type array
+fn cast_primitive_to_decimal<T: ArrayAccessor, F>(
+    array: T,
+    op: F,
+    precision: usize,
+    scale: usize,
+) -> Result<Arc<dyn Array>>
+where
+    F: Fn(T::Item) -> i128,
+{
+    #[allow(clippy::redundant_closure)]
+    let decimal_array = ArrayIter::new(array)
+        .map(|v| v.map(|v| op(v)))
+        .collect::<Decimal128Array>()
+        .with_precision_and_scale(precision, scale)?;
+
+    Ok(Arc::new(decimal_array))
 }
 
-// cast the floating-point array to defined decimal data type array
-macro_rules! cast_floating_point_to_decimal {
-    ($ARRAY: expr, $ARRAY_TYPE: ident, $PRECISION : ident, $SCALE : ident) => {{
-        let array = $ARRAY.as_any().downcast_ref::<$ARRAY_TYPE>().unwrap();
-        let mul = 10_f64.powi(*$SCALE as i32);
-        let decimal_array = array
-            .iter()
-            .map(|v| {
-                v.map(|v| {
-                    // with_precision_and_scale validates the
-                    // value is within range for the output precision
-                    ((v as f64) * mul) as i128
-                })
-            })
-            .collect::<Decimal128Array>()
-            .with_precision_and_scale(*$PRECISION, *$SCALE)?;
-        Ok(Arc::new(decimal_array))
-    }};
+fn cast_integer_to_decimal<T: ArrowNumericType>(
+    array: &PrimitiveArray<T>,
+    precision: usize,
+    scale: usize,
+) -> Result<Arc<dyn Array>> {
+    let mul: i128 = 10_i128.pow(scale as u32);
+
+    // with_precision_and_scale validates the
+    // value is within range for the output precision
+    cast_primitive_to_decimal(
+        array,
+        |v| v.to_isize().unwrap() as i128 * mul,
+        precision,
+        scale,
+    )
+}
+
+fn cast_floating_point_to_decimal<T: ArrowNumericType>(
+    array: &PrimitiveArray<T>,
+    precision: usize,
+    scale: usize,
+) -> Result<Arc<dyn Array>>
+where
+    <T as ArrowPrimitiveType>::Native: ToPrimitive,
+{
+    let mul = 10_f64.powi(scale as i32);
+
+    cast_primitive_to_decimal(
+        array,
+        |v| {
+            // with_precision_and_scale validates the
+            // value is within range for the output precision
+            ((num::ToPrimitive::to_f64(&v).unwrap()) * mul) as i128

Review Comment:
   I think this is now a checked conversion where previously it wasn't?



-- 
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: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org