Github user dbtsai commented on the issue:

    https://github.com/apache/spark/pull/18346
  
    Thanks, @viirya for this PR.
    
    We hit this issue, and @viirya was kindly helping us to find the root 
cause. This approach LGTM. One alternative approach we took in the end to 
unblock our use-case is having the CodeGenFallback to generate the code for all 
the children instead of going through the eval paths, and this works for us. I 
think the approach we took have benefits that we still can do the wholestage 
codegen together with the expression with CodeGenFallback without separating 
them into different path.
    
    @gatorsmile @cloud-fan any feedback?
    
    Thanks.
    
    ```scala
    import org.apache.spark.sql.catalyst.expressions.{Expression, 
LeafExpression, Nondeterministic, TernaryExpression}
    import org.apache.spark.sql.catalyst.expressions.codegen.{CodegenContext, 
ExprCode}
    
    trait TernaryCodegenFallback extends Expression { self: TernaryExpression =>
    
      private val className = classOf[TernaryCodegenFallback].getName
    
      def evalFromCodegen(value1: Any, value2: Any, value3: Any): Any = 
nullSafeEval(value1, value2, value3)
    
      protected def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
        foreach {
          case n: Nondeterministic => n.setInitialValues()
          case _ =>
        }
    
        // LeafNode does not need `input`
        val input = if (this.isInstanceOf[LeafExpression]) "null" else 
ctx.INPUT_ROW
        val idx = ctx.references.length
        ctx.references += this
        val objectTerm = ctx.freshName("obj")
        val placeHolder = ctx.registerComment(this.toString)
    
        val Seq(code1, code2, code3) = children.map(expr => expr.genCode(ctx))
    
        if (nullable) {
          ev.copy(code = s"""
            $placeHolder
            ${code1.code}
            ${code2.code}
            ${code3.code}
            Object $objectTerm = null;
            boolean ${ev.isNull} = ${code1.isNull} || ${code2.isNull} || 
${code3.isNull};
            if (!${ev.isNull}) {
              $objectTerm = (($className) references[$idx]).evalFromCodegen(
                ${code1.value}, ${code2.value}, ${code3.value}
              );
              ${ev.isNull} = $objectTerm == null;
            }
            ${ctx.javaType(this.dataType)} ${ev.value} = 
${ctx.defaultValue(this.dataType)};
            if (!${ev.isNull}) {
              ${ev.value} = (${ctx.boxedType(this.dataType)}) $objectTerm;
            }""")
        } else {
          ev.copy(code = s"""
            $placeHolder
            ${code1.code}
            ${code2.code}
            ${code3.code}
            Object $objectTerm = (($className) 
references[$idx]).evalFromCodegen(
              ${code1.value}, ${code2.value}, ${code3.value}
            );
            ${ctx.javaType(this.dataType)} ${ev.value} = 
(${ctx.boxedType(this.dataType)}) $objectTerm;
            """, isNull = "false")
        }
      }
    }
    ```


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