From 3ac22fedbc725d5eaefbd4c13e3fda3536a0b38b Mon Sep 17 00:00:00 2001 From: Josh Rosen Date: Tue, 8 Mar 2016 13:23:59 -0800 Subject: [PATCH 1/3] Escape quotes in graphviz labels. --- .../org/apache/spark/sql/execution/ui/SparkPlanGraph.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sql/core/src/main/scala/org/apache/spark/sql/execution/ui/SparkPlanGraph.scala b/sql/core/src/main/scala/org/apache/spark/sql/execution/ui/SparkPlanGraph.scala index 12e586ada5976..9531bc0b9ae80 100644 --- a/sql/core/src/main/scala/org/apache/spark/sql/execution/ui/SparkPlanGraph.scala +++ b/sql/core/src/main/scala/org/apache/spark/sql/execution/ui/SparkPlanGraph.scala @@ -55,6 +55,8 @@ private[ui] case class SparkPlanGraph( private[sql] object SparkPlanGraph { + def escapeQuotes(str: String): String = str.replace("\"", "\\\"") + /** * Build a SparkPlanGraph from the root of a SparkPlan tree. */ @@ -145,7 +147,7 @@ private[ui] class SparkPlanGraphNode( builder ++= values.mkString("\\n") } - s""" $id [label="${builder.toString()}"];""" + s""" $id [label="${SparkPlanGraph.escapeQuotes(builder.toString())}"];""" } } @@ -162,7 +164,7 @@ private[ui] class SparkPlanGraphCluster( override def makeDotNode(metricsValue: Map[Long, String]): String = { s""" | subgraph cluster${id} { - | label=${name}; + | label="${SparkPlanGraph.escapeQuotes(name)}"; | ${nodes.map(_.makeDotNode(metricsValue)).mkString(" \n")} | } """.stripMargin From 531adb7714d715281fc4f90916a9c64ec16ece44 Mon Sep 17 00:00:00 2001 From: Josh Rosen Date: Tue, 8 Mar 2016 13:31:07 -0800 Subject: [PATCH 2/3] Switch to StringEscapeUtils.escapeJava --- .../apache/spark/sql/execution/ui/SparkPlanGraph.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sql/core/src/main/scala/org/apache/spark/sql/execution/ui/SparkPlanGraph.scala b/sql/core/src/main/scala/org/apache/spark/sql/execution/ui/SparkPlanGraph.scala index 9531bc0b9ae80..15341d8dd9330 100644 --- a/sql/core/src/main/scala/org/apache/spark/sql/execution/ui/SparkPlanGraph.scala +++ b/sql/core/src/main/scala/org/apache/spark/sql/execution/ui/SparkPlanGraph.scala @@ -21,6 +21,8 @@ import java.util.concurrent.atomic.AtomicLong import scala.collection.mutable +import org.apache.commons.lang3.StringEscapeUtils + import org.apache.spark.sql.execution.SparkPlanInfo import org.apache.spark.sql.execution.metric.SQLMetrics @@ -55,8 +57,6 @@ private[ui] case class SparkPlanGraph( private[sql] object SparkPlanGraph { - def escapeQuotes(str: String): String = str.replace("\"", "\\\"") - /** * Build a SparkPlanGraph from the root of a SparkPlan tree. */ @@ -147,7 +147,7 @@ private[ui] class SparkPlanGraphNode( builder ++= values.mkString("\\n") } - s""" $id [label="${SparkPlanGraph.escapeQuotes(builder.toString())}"];""" + s""" $id [label="${StringEscapeUtils.escapeJava(builder.toString())}"];""" } } @@ -164,7 +164,7 @@ private[ui] class SparkPlanGraphCluster( override def makeDotNode(metricsValue: Map[Long, String]): String = { s""" | subgraph cluster${id} { - | label="${SparkPlanGraph.escapeQuotes(name)}"; + | label="${StringEscapeUtils.escapeJava(name)}"; | ${nodes.map(_.makeDotNode(metricsValue)).mkString(" \n")} | } """.stripMargin From 8bf1ba22f9b2910a52d686ae512a104c52ec60ce Mon Sep 17 00:00:00 2001 From: Josh Rosen Date: Tue, 8 Mar 2016 13:33:33 -0800 Subject: [PATCH 3/3] Avoid double-escaping. --- .../apache/spark/sql/execution/ui/SparkPlanGraph.scala | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/sql/core/src/main/scala/org/apache/spark/sql/execution/ui/SparkPlanGraph.scala b/sql/core/src/main/scala/org/apache/spark/sql/execution/ui/SparkPlanGraph.scala index 15341d8dd9330..83372aa2e930c 100644 --- a/sql/core/src/main/scala/org/apache/spark/sql/execution/ui/SparkPlanGraph.scala +++ b/sql/core/src/main/scala/org/apache/spark/sql/execution/ui/SparkPlanGraph.scala @@ -138,13 +138,11 @@ private[ui] class SparkPlanGraphNode( } if (values.nonEmpty) { - // If there are metrics, display each entry in a separate line. We should use an escaped - // "\n" here to follow the dot syntax. - // + // If there are metrics, display each entry in a separate line. // Note: whitespace between two "\n"s is to create an empty line between the name of // SparkPlan and metrics. If removing it, it won't display the empty line in UI. - builder ++= "\\n \\n" - builder ++= values.mkString("\\n") + builder ++= "\n \n" + builder ++= values.mkString("\n") } s""" $id [label="${StringEscapeUtils.escapeJava(builder.toString())}"];"""