cloud-fan commented on a change in pull request #29882:
URL: https://github.com/apache/spark/pull/29882#discussion_r513229177



##########
File path: 
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/arithmetic.scala
##########
@@ -313,21 +331,31 @@ case class Multiply(left: Expression, right: Expression) 
extends BinaryArithmeti
   override def exactMathMethod: Option[String] = Some("multiplyExact")
 }
 
-// Common base trait for Divide and Remainder, since these two classes are 
almost identical
-trait DivModLike extends BinaryArithmetic {
+// Common base class for Divide and Remainder, since these two classes are 
almost identical
+abstract class DivModLike(failOnError: Boolean) extends 
BinaryArithmetic(failOnError) {
 
   protected def decimalToDataTypeCodeGen(decimalResult: String): String = 
decimalResult
 
   override def nullable: Boolean = true
 
+  private lazy val isZero: Any => Boolean = right.dataType match {
+    case _: DecimalType => x => x.asInstanceOf[Decimal].isZero
+    case _ => x => x == 0
+  }
+
   final override def eval(input: InternalRow): Any = {
+    // evaluate right first as we have a chance to skip left if right is 0
     val input2 = right.eval(input)
-    if (input2 == null || input2 == 0) {
+    if (input2 == null || (!failOnError && isZero(input2))) {
       null
     } else {
       val input1 = left.eval(input)
       if (input1 == null) {
         null
+      } else if (isZero(input2)) {
+        // `failOnError` is always true here
+        throw new ArithmeticException("divide by zero")
+        null

Review comment:
       no need a return value after `throw`

##########
File path: 
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/arithmetic.scala
##########
@@ -313,21 +331,31 @@ case class Multiply(left: Expression, right: Expression) 
extends BinaryArithmeti
   override def exactMathMethod: Option[String] = Some("multiplyExact")
 }
 
-// Common base trait for Divide and Remainder, since these two classes are 
almost identical
-trait DivModLike extends BinaryArithmetic {
+// Common base class for Divide and Remainder, since these two classes are 
almost identical
+abstract class DivModLike(failOnError: Boolean) extends 
BinaryArithmetic(failOnError) {
 
   protected def decimalToDataTypeCodeGen(decimalResult: String): String = 
decimalResult
 
   override def nullable: Boolean = true
 
+  private lazy val isZero: Any => Boolean = right.dataType match {
+    case _: DecimalType => x => x.asInstanceOf[Decimal].isZero
+    case _ => x => x == 0
+  }
+
   final override def eval(input: InternalRow): Any = {
+    // evaluate right first as we have a chance to skip left if right is 0
     val input2 = right.eval(input)
-    if (input2 == null || input2 == 0) {
+    if (input2 == null || (!failOnError && isZero(input2))) {
       null
     } else {
       val input1 = left.eval(input)
       if (input1 == null) {
         null
+      } else if (isZero(input2)) {
+        // `failOnError` is always true here
+        throw new ArithmeticException("divide by zero")
+        null

Review comment:
       don't need a return value after `throw`




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

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



---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscr...@spark.apache.org
For additional commands, e-mail: reviews-h...@spark.apache.org

Reply via email to