viirya commented on code in PR #1983:
URL: https://github.com/apache/arrow-rs/pull/1983#discussion_r916223279


##########
arrow/src/compute/kernels/arithmetic.rs:
##########
@@ -126,44 +126,68 @@ where
     let null_bit_buffer =
         combine_option_bitmap(&[left.data_ref(), right.data_ref()], 
left.len())?;
 
-    let buffer = if let Some(b) = &null_bit_buffer {
-        let values = left.values().iter().zip(right.values()).enumerate().map(
-            |(i, (left, right))| {
-                let is_valid = unsafe { bit_util::get_bit_raw(b.as_ptr(), i) };
-                if is_valid {
-                    if right.is_zero() {
-                        Err(ArrowError::DivideByZero)
-                    } else {
-                        Ok(op(*left, *right))
-                    }
+    math_checked_divide_op_on_iters(
+        left.into_iter(),
+        right.into_iter(),
+        op,
+        left.len(),
+        null_bit_buffer,
+    )
+}
+
+/// Helper function for operations where a valid `0` on the right array should
+/// result in an [ArrowError::DivideByZero], namely the division and modulo 
operations
+///
+/// # Errors
+///
+/// This function errors if:
+/// * the arrays have different lengths
+/// * there is an element where both left and right values are valid and the 
right value is `0`
+fn math_checked_divide_op_on_iters<T, F>(
+    left: impl Iterator<Item = Option<T::Native>>,
+    right: impl Iterator<Item = Option<T::Native>>,
+    op: F,
+    len: usize,
+    null_bit_buffer: Option<Buffer>,
+) -> Result<PrimitiveArray<T>>
+where
+    T: ArrowNumericType,
+    T::Native: One + Zero,
+    F: Fn(T::Native, T::Native) -> T::Native,
+{
+    let buffer = if null_bit_buffer.is_some() {
+        let values = left.zip(right).map(|(left, right)| {
+            if let (Some(l), Some(r)) = (left, right) {
+                if r.is_zero() {
+                    Err(ArrowError::DivideByZero)
                 } else {
-                    Ok(T::default_value())
+                    Ok(op(l, r))
                 }
-            },
-        );
+            } else {
+                Ok(T::default_value())

Review Comment:
   This follows the divide kernel did before. I think for the case (left or 
right is None), the value is not important, so it just put a default value 
there.



-- 
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-unsubscr...@arrow.apache.org

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

Reply via email to