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]