@@ -586,7 +586,7 @@ abstract class TernaryExpression extends Expression {
586586
587587object  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