Github user davies commented on a diff in the pull request:

    https://github.com/apache/spark/pull/6479#discussion_r31691732
  
    --- Diff: 
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala
 ---
    @@ -313,295 +318,309 @@ abstract class CodeGenerator[InType <: AnyRef, 
OutType <: AnyRef] extends Loggin
                 }
                 val $nullTerm = false
                 val $primitiveTerm = $funcName
    -        """.children
    +        """
           */
     
           case GreaterThan(e1 @ NumericType(), e2 @ NumericType()) =>
    -        (e1, e2).evaluateAs (BooleanType) { case (eval1, eval2) => 
q"$eval1 > $eval2" }
    +        (e1, e2).evaluateAs (BooleanType) { case (eval1, eval2) => 
s"$eval1 > $eval2" }
           case GreaterThanOrEqual(e1 @ NumericType(), e2 @ NumericType()) =>
    -        (e1, e2).evaluateAs (BooleanType) { case (eval1, eval2) => 
q"$eval1 >= $eval2" }
    +        (e1, e2).evaluateAs (BooleanType) { case (eval1, eval2) => 
s"$eval1 >= $eval2" }
           case LessThan(e1 @ NumericType(), e2 @ NumericType()) =>
    -        (e1, e2).evaluateAs (BooleanType) { case (eval1, eval2) => 
q"$eval1 < $eval2" }
    +        (e1, e2).evaluateAs (BooleanType) { case (eval1, eval2) => 
s"$eval1 < $eval2" }
           case LessThanOrEqual(e1 @ NumericType(), e2 @ NumericType()) =>
    -        (e1, e2).evaluateAs (BooleanType) { case (eval1, eval2) => 
q"$eval1 <= $eval2" }
    +        (e1, e2).evaluateAs (BooleanType) { case (eval1, eval2) => 
s"$eval1 <= $eval2" }
     
           case And(e1, e2) =>
    -        val eval1 = expressionEvaluator(e1)
    -        val eval2 = expressionEvaluator(e2)
    -
    -        q"""
    -          ..${eval1.code}
    -          var $nullTerm = false
    -          var $primitiveTerm: ${termForType(BooleanType)} = false
    -
    -          if (!${eval1.nullTerm} && ${eval1.primitiveTerm} == false) {
    +        val eval1 = expressionEvaluator(e1, ctx)
    +        val eval2 = expressionEvaluator(e2, ctx)
    +        // TODO(davies): This is different than And.eval()
    +        s"""
    +          ${eval1.code}
    +          boolean $nullTerm = false;
    +          boolean $primitiveTerm  = false;
    +
    +          if (!${eval1.nullTerm} && !${eval1.primitiveTerm}) {
               } else {
    -            ..${eval2.code}
    -            if (!${eval2.nullTerm} && ${eval2.primitiveTerm} == false) {
    +            ${eval2.code}
    +            if (!${eval2.nullTerm} && !${eval2.primitiveTerm}) {
                 } else if (!${eval1.nullTerm} && !${eval2.nullTerm}) {
    -              $primitiveTerm = true
    +              $primitiveTerm = true;
                 } else {
    -              $nullTerm = true
    +              $nullTerm = true;
                 }
               }
    -         """.children
    +         """
     
           case Or(e1, e2) =>
    -        val eval1 = expressionEvaluator(e1)
    -        val eval2 = expressionEvaluator(e2)
    +        val eval1 = expressionEvaluator(e1, ctx)
    +        val eval2 = expressionEvaluator(e2, ctx)
     
    -        q"""
    -          ..${eval1.code}
    -          var $nullTerm = false
    -          var $primitiveTerm: ${termForType(BooleanType)} = false
    +        s"""
    +          ${eval1.code}
    +          boolean $nullTerm = false;
    +          boolean $primitiveTerm = false;
     
               if (!${eval1.nullTerm} && ${eval1.primitiveTerm}) {
    -            $primitiveTerm = true
    +            $primitiveTerm = true;
               } else {
    -            ..${eval2.code}
    +            ${eval2.code}
                 if (!${eval2.nullTerm} && ${eval2.primitiveTerm}) {
    -              $primitiveTerm = true
    +              $primitiveTerm = true;
                 } else if (!${eval1.nullTerm} && !${eval2.nullTerm}) {
    -              $primitiveTerm = false
    +              $primitiveTerm = false;
                 } else {
    -              $nullTerm = true
    +              $nullTerm = true;
                 }
               }
    -         """.children
    +         """
     
           case Not(child) =>
             // Uh, bad function name...
    -        child.castOrNull(c => q"!$c", BooleanType)
    -
    -      case Add(e1, e2) => (e1, e2) evaluate { case (eval1, eval2) => 
q"$eval1 + $eval2" }
    -      case Subtract(e1, e2) => (e1, e2) evaluate { case (eval1, eval2) => 
q"$eval1 - $eval2" }
    -      case Multiply(e1, e2) => (e1, e2) evaluate { case (eval1, eval2) => 
q"$eval1 * $eval2" }
    +        child.castOrNull(c => s"!$c", BooleanType)
    +
    +      case Add(e1 @ DecimalType(), e2 @ DecimalType()) =>
    +        (e1, e2) evaluate { case (eval1, eval2) => 
s"$eval1.$$plus($eval2)" }
    +      case Subtract(e1 @ DecimalType(), e2 @ DecimalType()) =>
    +        (e1, e2) evaluate { case (eval1, eval2) => 
s"$eval1.$$minus($eval2)" }
    +      case Multiply(e1 @ DecimalType(), e2 @ DecimalType()) =>
    +        (e1, e2) evaluate { case (eval1, eval2) => 
s"$eval1.$$times($eval2)" }
    +      case Divide(e1 @ DecimalType(), e2 @ DecimalType()) =>
    +        val eval1 = expressionEvaluator(e1, ctx)
    +        val eval2 = expressionEvaluator(e2, ctx)
    +        eval1.code + eval2.code +
    +          s"""
    +          boolean $nullTerm = false;
    +          ${primitiveForType(e1.dataType)} $primitiveTerm = null;
    +          if (${eval1.nullTerm} || ${eval2.nullTerm} || 
${eval2.primitiveTerm}.isZero()) {
    +            $nullTerm = true;
    +          } else {
    +            $primitiveTerm = 
${eval1.primitiveTerm}.$$div${eval2.primitiveTerm});
    +          }
    +          """
    +      case Remainder(e1 @ DecimalType(), e2 @ DecimalType()) =>
    +        val eval1 = expressionEvaluator(e1, ctx)
    +        val eval2 = expressionEvaluator(e2, ctx)
    +        eval1.code + eval2.code +
    +          s"""
    +          boolean $nullTerm = false;
    +          ${primitiveForType(e1.dataType)} $primitiveTerm = 0;
    +          if (${eval1.nullTerm} || ${eval2.nullTerm} || 
${eval2.primitiveTerm}.isZero()) {
    +            $nullTerm = true;
    +          } else {
    +            $primitiveTerm = 
${eval1.primitiveTerm}.remainder(${eval2.primitiveTerm});
    +          }
    +         """
    +
    +      case Add(e1, e2) =>
    +        (e1, e2) evaluate { case (eval1, eval2) => s"$eval1 + $eval2" }
    +      case Subtract(e1, e2) =>
    +        (e1, e2) evaluate { case (eval1, eval2) => s"$eval1 - $eval2" }
    +      case Multiply(e1, e2) =>
    +        (e1, e2) evaluate { case (eval1, eval2) => s"$eval1 * $eval2" }
           case Divide(e1, e2) =>
    -        val eval1 = expressionEvaluator(e1)
    -        val eval2 = expressionEvaluator(e2)
    -
    -        eval1.code ++ eval2.code ++
    -        q"""
    -          var $nullTerm = false
    -          var $primitiveTerm: ${termForType(e1.dataType)} = 0
    -
    -          if (${eval1.nullTerm} || ${eval2.nullTerm} ) {
    -            $nullTerm = true
    -          } else if (${eval2.primitiveTerm} == 0)
    -            $nullTerm = true
    -          else {
    -            $primitiveTerm = ${eval1.primitiveTerm} / 
${eval2.primitiveTerm}
    +        val eval1 = expressionEvaluator(e1, ctx)
    +        val eval2 = expressionEvaluator(e2, ctx)
    +        eval1.code + eval2.code +
    +        s"""
    +          boolean $nullTerm = false;
    +          ${primitiveForType(e1.dataType)} $primitiveTerm = 0;
    +          if (${eval1.nullTerm} || ${eval2.nullTerm} || 
${eval2.primitiveTerm} == 0) {
    +            $nullTerm = true;
    +          } else {
    +            $primitiveTerm = ${eval1.primitiveTerm} / 
${eval2.primitiveTerm};
               }
    -         """.children
    -
    +        """
           case Remainder(e1, e2) =>
    -        val eval1 = expressionEvaluator(e1)
    -        val eval2 = expressionEvaluator(e2)
    -
    -        eval1.code ++ eval2.code ++
    -        q"""
    -          var $nullTerm = false
    -          var $primitiveTerm: ${termForType(e1.dataType)} = 0
    -
    -          if (${eval1.nullTerm} || ${eval2.nullTerm} ) {
    -            $nullTerm = true
    -          } else if (${eval2.primitiveTerm} == 0)
    -            $nullTerm = true
    -          else {
    -            $nullTerm = false
    -            $primitiveTerm = ${eval1.primitiveTerm} % 
${eval2.primitiveTerm}
    +        val eval1 = expressionEvaluator(e1, ctx)
    +        val eval2 = expressionEvaluator(e2, ctx)
    +        eval1.code + eval2.code +
    +        s"""
    +          boolean $nullTerm = false;
    +          ${primitiveForType(e1.dataType)} $primitiveTerm = 0;
    +          if (${eval1.nullTerm} || ${eval2.nullTerm} || 
${eval2.primitiveTerm} == 0) {
    +            $nullTerm = true;
    +          } else {
    +            $primitiveTerm = ${eval1.primitiveTerm} % 
${eval2.primitiveTerm};
               }
    -         """.children
    +         """
     
           case IsNotNull(e) =>
    -        val eval = expressionEvaluator(e)
    -        q"""
    -          ..${eval.code}
    -          var $nullTerm = false
    -          var $primitiveTerm: ${termForType(BooleanType)} = 
!${eval.nullTerm}
    -        """.children
    +        val eval = expressionEvaluator(e, ctx)
    +        s"""
    +          ${eval.code}
    +          boolean $nullTerm = false;
    +          boolean $primitiveTerm = !${eval.nullTerm};
    +        """
     
           case IsNull(e) =>
    -        val eval = expressionEvaluator(e)
    -        q"""
    -          ..${eval.code}
    -          var $nullTerm = false
    -          var $primitiveTerm: ${termForType(BooleanType)} = 
${eval.nullTerm}
    -        """.children
    -
    -      case c @ Coalesce(children) =>
    -        q"""
    -          var $nullTerm = true
    -          var $primitiveTerm: ${termForType(c.dataType)} = 
${defaultPrimitive(c.dataType)}
    -        """.children ++
    +        val eval = expressionEvaluator(e, ctx)
    +        s"""
    +          ${eval.code}
    +          boolean $nullTerm = false;
    +          boolean $primitiveTerm = ${eval.nullTerm};
    +        """
    +
    +      case e @ Coalesce(children) =>
    +        s"""
    +          boolean $nullTerm = true;
    +          ${primitiveForType(e.dataType)} $primitiveTerm = 
${defaultPrimitive(e.dataType)};
    +        """ +
             children.map { c =>
    -          val eval = expressionEvaluator(c)
    -          q"""
    +          val eval = expressionEvaluator(c, ctx)
    +          s"""
                 if($nullTerm) {
    -              ..${eval.code}
    +              ${eval.code}
                   if(!${eval.nullTerm}) {
    -                $nullTerm = false
    -                $primitiveTerm = ${eval.primitiveTerm}
    +                $nullTerm = false;
    +                $primitiveTerm = ${eval.primitiveTerm};
                   }
                 }
               """
    -        }
    +        }.mkString("\n")
     
    -      case i @ expressions.If(condition, trueValue, falseValue) =>
    -        val condEval = expressionEvaluator(condition)
    -        val trueEval = expressionEvaluator(trueValue)
    -        val falseEval = expressionEvaluator(falseValue)
    +      case e @ expressions.If(condition, trueValue, falseValue) =>
    +        val condEval = expressionEvaluator(condition, ctx)
    +        val trueEval = expressionEvaluator(trueValue, ctx)
    +        val falseEval = expressionEvaluator(falseValue, ctx)
     
    -        q"""
    -          var $nullTerm = false
    -          var $primitiveTerm: ${termForType(i.dataType)} = 
${defaultPrimitive(i.dataType)}
    -          ..${condEval.code}
    +        s"""
    +          boolean $nullTerm = false;
    +          ${primitiveForType(e.dataType)} $primitiveTerm = 
${defaultPrimitive(e.dataType)};
    +          ${condEval.code}
               if(!${condEval.nullTerm} && ${condEval.primitiveTerm}) {
    -            ..${trueEval.code}
    -            $nullTerm = ${trueEval.nullTerm}
    -            $primitiveTerm = ${trueEval.primitiveTerm}
    +            ${trueEval.code}
    +            $nullTerm = ${trueEval.nullTerm};
    +            $primitiveTerm = ${trueEval.primitiveTerm};
               } else {
    -            ..${falseEval.code}
    -            $nullTerm = ${falseEval.nullTerm}
    -            $primitiveTerm = ${falseEval.primitiveTerm}
    +            ${falseEval.code}
    +            $nullTerm = ${falseEval.nullTerm};
    +            $primitiveTerm = ${falseEval.primitiveTerm};
               }
    -        """.children
    +        """
     
           case NewSet(elementType) =>
    -        q"""
    -          val $nullTerm = false
    -          val $primitiveTerm = new ${hashSetForType(elementType)}()
    -        """.children
    +        s"""
    +          boolean $nullTerm = false;
    +          ${hashSetForType(elementType)} $primitiveTerm = new 
${hashSetForType(elementType)}();
    +        """
     
           case AddItemToSet(item, set) =>
    -        val itemEval = expressionEvaluator(item)
    -        val setEval = expressionEvaluator(set)
    +        val itemEval = expressionEvaluator(item, ctx)
    +        val setEval = expressionEvaluator(set, ctx)
     
             val elementType = 
set.dataType.asInstanceOf[OpenHashSetUDT].elementType
    +        val htype = hashSetForType(elementType)
     
    -        itemEval.code ++ setEval.code ++
    -        q"""
    -           if (!${itemEval.nullTerm}) {
    -             ${setEval.primitiveTerm}
    -               .asInstanceOf[${hashSetForType(elementType)}]
    -               .add(${itemEval.primitiveTerm})
    +        itemEval.code + setEval.code +
    +        s"""
    +           if (!${itemEval.nullTerm} && !${setEval.nullTerm}) {
    +             
(($htype)${setEval.primitiveTerm}).add(${itemEval.primitiveTerm});
                }
    -
    -           val $nullTerm = false
    -           val $primitiveTerm = ${setEval.primitiveTerm}
    -         """.children
    +           boolean $nullTerm = false;
    +           ${htype} $primitiveTerm = ($htype)${setEval.primitiveTerm};
    +         """
     
           case CombineSets(left, right) =>
    -        val leftEval = expressionEvaluator(left)
    -        val rightEval = expressionEvaluator(right)
    +        val leftEval = expressionEvaluator(left, ctx)
    +        val rightEval = expressionEvaluator(right, ctx)
     
             val elementType = 
left.dataType.asInstanceOf[OpenHashSetUDT].elementType
    +        val htype = hashSetForType(elementType)
     
    -        leftEval.code ++ rightEval.code ++
    -        q"""
    -          val $nullTerm = false
    -          var $primitiveTerm: ${hashSetForType(elementType)} = null
    -
    -          {
    -            val leftSet = 
${leftEval.primitiveTerm}.asInstanceOf[${hashSetForType(elementType)}]
    -            val rightSet = 
${rightEval.primitiveTerm}.asInstanceOf[${hashSetForType(elementType)}]
    -            val iterator = rightSet.iterator
    -            while (iterator.hasNext) {
    -              leftSet.add(iterator.next())
    -            }
    -            $primitiveTerm = leftSet
    -          }
    -        """.children
    +        leftEval.code + rightEval.code +
    +        s"""
    +          boolean $nullTerm = false;
    +          ${htype} $primitiveTerm =
    +            (${htype})${leftEval.primitiveTerm};
    +          $primitiveTerm.union((${htype})${rightEval.primitiveTerm});
    +        """
     
    -      case MaxOf(e1, e2) =>
    -        val eval1 = expressionEvaluator(e1)
    -        val eval2 = expressionEvaluator(e2)
    +      case MaxOf(e1, e2) if !e1.dataType.isInstanceOf[DecimalType] =>
    --- End diff --
    
    We can not compare two Decimal by `a > b`


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to