This is an automated email from the ASF dual-hosted git repository.

alamb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-datafusion.git


The following commit(s) were added to refs/heads/master by this push:
     new d55a105  Support modulus op (#577)
d55a105 is described below

commit d55a10569b3a24195bed2d67cc6414c63b6b2336
Author: Gang Liao <[email protected]>
AuthorDate: Tue Jun 22 15:42:18 2021 -0700

    Support modulus op (#577)
---
 datafusion/src/physical_plan/expressions/binary.rs | 52 ++++++++++++++--------
 1 file changed, 34 insertions(+), 18 deletions(-)

diff --git a/datafusion/src/physical_plan/expressions/binary.rs 
b/datafusion/src/physical_plan/expressions/binary.rs
index a69b776..102b701 100644
--- a/datafusion/src/physical_plan/expressions/binary.rs
+++ b/datafusion/src/physical_plan/expressions/binary.rs
@@ -20,7 +20,7 @@ use std::{any::Any, sync::Arc};
 use arrow::array::TimestampMillisecondArray;
 use arrow::array::*;
 use arrow::compute::kernels::arithmetic::{
-    add, divide, divide_scalar, multiply, subtract,
+    add, divide, divide_scalar, modulus, modulus_scalar, multiply, subtract,
 };
 use arrow::compute::kernels::boolean::{and_kleene, or_kleene};
 use arrow::compute::kernels::comparison::{eq, gt, gt_eq, lt, lt_eq, neq};
@@ -360,14 +360,11 @@ fn common_binary_type(
         }
         // for math expressions, the final value of the coercion is also the 
return type
         // because coercion favours higher information types
-        Operator::Plus | Operator::Minus | Operator::Divide | 
Operator::Multiply => {
-            numerical_coercion(lhs_type, rhs_type)
-        }
-        Operator::Modulus => {
-            return Err(DataFusionError::NotImplemented(
-                "Modulus operator is still not supported".to_string(),
-            ))
-        }
+        Operator::Plus
+        | Operator::Minus
+        | Operator::Modulus
+        | Operator::Divide
+        | Operator::Multiply => numerical_coercion(lhs_type, rhs_type),
     };
 
     // re-write the error message of failed coercions to include the 
operator's information
@@ -408,12 +405,11 @@ pub fn binary_operator_data_type(
         | Operator::GtEq
         | Operator::LtEq => Ok(DataType::Boolean),
         // math operations return the same value as the common coerced type
-        Operator::Plus | Operator::Minus | Operator::Divide | 
Operator::Multiply => {
-            Ok(common_type)
-        }
-        Operator::Modulus => Err(DataFusionError::NotImplemented(
-            "Modulus operator is still not supported".to_string(),
-        )),
+        Operator::Plus
+        | Operator::Minus
+        | Operator::Divide
+        | Operator::Multiply
+        | Operator::Modulus => Ok(common_type),
     }
 }
 
@@ -473,6 +469,9 @@ impl PhysicalExpr for BinaryExpr {
                     Operator::Divide => {
                         binary_primitive_array_op_scalar!(array, 
scalar.clone(), divide)
                     }
+                    Operator::Modulus => {
+                        binary_primitive_array_op_scalar!(array, 
scalar.clone(), modulus)
+                    }
                     // if scalar operation is not supported - fallback to 
array implementation
                     _ => None,
                 }
@@ -522,6 +521,7 @@ impl PhysicalExpr for BinaryExpr {
             Operator::Minus => binary_primitive_array_op!(left, right, 
subtract),
             Operator::Multiply => binary_primitive_array_op!(left, right, 
multiply),
             Operator::Divide => binary_primitive_array_op!(left, right, 
divide),
+            Operator::Modulus => binary_primitive_array_op!(left, right, 
modulus),
             Operator::And => {
                 if left_data_type == DataType::Boolean {
                     boolean_op!(left, right, and_kleene)
@@ -544,9 +544,6 @@ impl PhysicalExpr for BinaryExpr {
                     )));
                 }
             }
-            Operator::Modulus => Err(DataFusionError::NotImplemented(
-                "Modulus operator is still not supported".to_string(),
-            )),
         };
         result.map(|a| ColumnarValue::Array(a))
     }
@@ -996,6 +993,25 @@ mod tests {
         Ok(())
     }
 
+    #[test]
+    fn modulus_op() -> Result<()> {
+        let schema = Arc::new(Schema::new(vec![
+            Field::new("a", DataType::Int32, false),
+            Field::new("b", DataType::Int32, false),
+        ]));
+        let a = Arc::new(Int32Array::from(vec![8, 32, 128, 512, 2048]));
+        let b = Arc::new(Int32Array::from(vec![2, 4, 7, 14, 32]));
+
+        apply_arithmetic::<Int32Type>(
+            schema,
+            vec![a, b],
+            Operator::Modulus,
+            Int32Array::from(vec![0, 0, 2, 8, 0]),
+        )?;
+
+        Ok(())
+    }
+
     fn apply_arithmetic<T: ArrowNumericType>(
         schema: SchemaRef,
         data: Vec<ArrayRef>,

Reply via email to