Skip to content

Commit 64e93ec

Browse files
committed
Reduce duplication.
1 parent 250e8a6 commit 64e93ec

File tree

1 file changed

+36
-24
lines changed
  • sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions

1 file changed

+36
-24
lines changed

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Expression.scala

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ abstract class TernaryExpression extends Expression {
586586

587587
object ExprCodegen {
588588

589-
val placeHolderForResultCode = "__PLACEHOLDER__"
589+
private val placeHolderForResultCode = "__PLACEHOLDER__"
590590

591591
def isNotWholeStageCodegen(ctx: CodegenContext): Boolean =
592592
ctx.INPUT_ROW != null && ctx.currentVars == null
@@ -626,39 +626,51 @@ object ExprCodegen {
626626
}
627627
}
628628

629-
// Generates codes safe from 64k limit for children expressions.
629+
// Generating evaluation code for children expressions. We fold the code for each child
630+
// expression from right to left. Once code length will be larger than the threshold, we
631+
// put the code from next child expression into a method to prevent possible 64k limit.
630632
def genCodeWithChildren(
631633
ctx: CodegenContext,
632634
expr: Expression): (String, Seq[ExprCode]) = {
633-
val rawGenCode = expr.children.map(_.genCode(ctx))
635+
val genCodeForChildren = expr.children.map(_.genCode(ctx))
634636

635-
val childrenEval = if (expr.nullable) {
636-
var childIdx = expr.children.length - 1
637-
rawGenCode.foldRight(placeHolderForResultCode) { case (childCode, curCode) =>
638-
if (curCode.length + childCode.code.trim.length > 1024) {
639-
genChildCodeInFunction(ctx, expr.children(childIdx), childCode)
640-
}
641-
val code = childCode.code +
637+
// For nullable expression, the code of children expression is wrapped in "if" blocks
638+
// for null check. We leave a special placeholder string which will be replaced with
639+
// evaluation code of this expression later.
640+
val initCode = if (expr.nullable) {
641+
placeHolderForResultCode
642+
} else {
643+
""
644+
}
645+
646+
var childIdx = expr.children.length - 1
647+
val childrenEval = genCodeForChildren.foldRight(initCode) { case (childCode, curCode) =>
648+
if (curCode.length + childCode.code.trim.length > 1024) {
649+
genChildCodeInFunction(ctx, expr.children(childIdx), childCode)
650+
}
651+
val code = if (expr.nullable) {
652+
childCode.code +
642653
ctx.nullSafeExec(expr.children(childIdx).nullable, childCode.isNull) {
643654
curCode
644655
}
645-
childIdx -= 1
646-
code
647-
}
648-
} else {
649-
var childIdx = expr.children.length - 1
650-
rawGenCode.foldRight("") { case (childCode, curCode) =>
651-
if (curCode.length + childCode.code.trim.length > 1024) {
652-
genChildCodeInFunction(ctx, expr.children(childIdx), childCode)
653-
}
654-
val code = childCode.code + "\n" + curCode
655-
childIdx -= 1
656-
code
656+
} else {
657+
childCode.code + "\n" + curCode
657658
}
659+
childIdx -= 1
660+
code
658661
}
659-
(childrenEval, rawGenCode)
662+
(childrenEval, genCodeForChildren)
660663
}
661664

665+
/**
666+
* Generating evaluation code for binary and ternary expressions for now.
667+
* If either of the sub-expressions is null, the result of this computation
668+
* is assumed to be null.
669+
*
670+
* @param childrenEval Evaluation code for all sub-expressions.
671+
* @param resultCode Evaluation code for the current expression. The evaluation is based on
672+
* the values of `childrenEval`.
673+
*/
662674
def nullSafeCodeGen(
663675
ctx: CodegenContext,
664676
ev: ExprCode,
@@ -670,7 +682,7 @@ object ExprCodegen {
670682
${ev.isNull} = false; // resultCode could change nullability.
671683
$resultCode
672684
"""
673-
val nullSafeEval = childrenEval.replace(ExprCodegen.placeHolderForResultCode, insertCode)
685+
val nullSafeEval = childrenEval.replace(placeHolderForResultCode, insertCode)
674686

675687
ev.copy(code = s"""
676688
boolean ${ev.isNull} = true;

0 commit comments

Comments
 (0)