aboutsummaryrefslogtreecommitdiff
path: root/sql/catalyst
diff options
context:
space:
mode:
authorYin Huai <yhuai@databricks.com>2015-12-01 16:24:04 -0800
committerYin Huai <yhuai@databricks.com>2015-12-01 16:24:04 -0800
commit5872a9d89fe2720c2bcb1fc7494136947a72581c (patch)
treed89309457bcff6f45ba7301e681950782959e2f8 /sql/catalyst
parent5a8b5fdd6ffa58f015cdadf3f2c6df78e0a388ad (diff)
downloadspark-5872a9d89fe2720c2bcb1fc7494136947a72581c.tar.gz
spark-5872a9d89fe2720c2bcb1fc7494136947a72581c.tar.bz2
spark-5872a9d89fe2720c2bcb1fc7494136947a72581c.zip
[SPARK-11352][SQL] Escape */ in the generated comments.
https://issues.apache.org/jira/browse/SPARK-11352 Author: Yin Huai <yhuai@databricks.com> Closes #10072 from yhuai/SPARK-11352.
Diffstat (limited to 'sql/catalyst')
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Expression.scala10
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodegenFallback.scala2
-rw-r--r--sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/CodeGenerationSuite.scala9
3 files changed, 18 insertions, 3 deletions
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Expression.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Expression.scala
index b55d3653a7..4ee6542455 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Expression.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Expression.scala
@@ -95,7 +95,7 @@ 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")
@@ -103,7 +103,7 @@ abstract class Expression extends TreeNode[Expression] {
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)
}
}
@@ -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("*/", "\\*\\/")
}
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodegenFallback.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodegenFallback.scala
index a31574c251..26fb143d1e 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodegenFallback.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodegenFallback.scala
@@ -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)};
diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/CodeGenerationSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/CodeGenerationSuite.scala
index 002ed16dcf..fe754240dc 100644
--- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/CodeGenerationSuite.scala
+++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/CodeGenerationSuite.scala
@@ -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("*/")))
+ }
}