Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,15 @@ abstract class Expression extends TreeNode[Expression] {
ctx.subExprEliminationExprs.get(this).map { subExprState =>
// This expression is repeated meaning the code to evaluated has already been added
// as a function and called in advance. Just use it.
val code = s"/* $this */"
val code = s"/* ${this.toCommentSafeString} */"
GeneratedExpressionCode(code, subExprState.isNull, subExprState.value)
}.getOrElse {
val isNull = ctx.freshName("isNull")
val primitive = ctx.freshName("primitive")
val ve = GeneratedExpressionCode("", isNull, primitive)
ve.code = genCode(ctx, ve)
// Add `this` in the comment.
ve.copy(s"/* $this */\n" + ve.code.trim)
ve.copy(s"/* ${this.toCommentSafeString} */\n" + ve.code.trim)
}
}

Expand Down Expand Up @@ -214,6 +214,12 @@ abstract class Expression extends TreeNode[Expression] {
}

override def toString: String = prettyName + flatArguments.mkString("(", ",", ")")

/**
* Returns the string representation of this expression that is safe to be put in
* code comments of generated code.
*/
protected def toCommentSafeString: String = this.toString.replace("*/", "\\*\\/")
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ trait CodegenFallback extends Expression {
ctx.references += this
val objectTerm = ctx.freshName("obj")
s"""
/* expression: ${this} */
/* expression: ${this.toCommentSafeString} */
java.lang.Object $objectTerm = expressions[${ctx.references.size - 1}].eval(${ctx.INPUT_ROW});
boolean ${ev.isNull} = $objectTerm == null;
${ctx.javaType(this.dataType)} ${ev.value} = ${ctx.defaultValue(this.dataType)};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,13 @@ class CodeGenerationSuite extends SparkFunSuite with ExpressionEvalHelper {
unsafeRow.getStruct(3, 1).getStruct(0, 2).setInt(1, 4)
assert(internalRow === internalRow2)
}

test("*/ in the data") {
// When */ appears in a comment block (i.e. in /**/), code gen will break.
// So, in Expression and CodegenFallback, we escape */ to \*\/.
checkEvaluation(
EqualTo(BoundReference(0, StringType, false), Literal.create("*/", StringType)),
true,
InternalRow(UTF8String.fromString("*/")))
}
}