This is an automated email from the ASF dual-hosted git repository.
dongjoon pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push:
new 15ea9de88b8d [SPARK-47503][SQL] Make `makeDotNode` escape graph node
name always
15ea9de88b8d is described below
commit 15ea9de88b8d8a87daa6abbc8e80c439e2d38e03
Author: Alexey <alexey13>
AuthorDate: Sun Mar 24 00:16:05 2024 -0700
[SPARK-47503][SQL] Make `makeDotNode` escape graph node name always
### What changes were proposed in this pull request?
To prevent corruption of dot file a node name should be escaped even if
there is no metrics to display
### Why are the changes needed?
This pr fixes a bug in spark history server which fails to display query
for cached JDBC relation named in quotes.
### Does this PR introduce any user-facing change?
No.
### How was this patch tested?
Unit test.
### Was this patch authored or co-authored using generative AI tooling?
No.
Closes #45640 from alex35736/SPARK-47503.
Lead-authored-by: Alexey <alexey13>
Co-authored-by: Dongjoon Hyun <[email protected]>
Signed-off-by: Dongjoon Hyun <[email protected]>
---
.../spark/sql/execution/ui/SparkPlanGraph.scala | 2 +-
.../sql/execution/ui/SparkPlanGraphSuite.scala | 46 ++++++++++++++++++++++
2 files changed, 47 insertions(+), 1 deletion(-)
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 11ba3cd05e26..f94d7dc7ab4c 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
@@ -189,7 +189,7 @@ class SparkPlanGraphNode(
} else {
// SPARK-30684: when there is no metrics, add empty lines to increase
the height of the node,
// so that there won't be gaps between an edge and a small node.
- s"<br><b>$name</b><br><br>"
+ s"<br><b>${StringEscapeUtils.escapeJava(name)}</b><br><br>"
}
s""" $id [id="$nodeId" labelType="html" label="$labelStr"
tooltip="$tooltip"];"""
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/ui/SparkPlanGraphSuite.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/ui/SparkPlanGraphSuite.scala
new file mode 100644
index 000000000000..975dbc1a1d8d
--- /dev/null
+++
b/sql/core/src/test/scala/org/apache/spark/sql/execution/ui/SparkPlanGraphSuite.scala
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.spark.sql.execution.ui
+
+import org.apache.spark.SparkFunSuite
+
+class SparkPlanGraphSuite extends SparkFunSuite {
+ test("SPARK-47503: name of a node should be escaped even if there is no
metrics") {
+ val planGraphNode = new SparkPlanGraphNode(
+ id = 24,
+ name = "Scan JDBCRelation(\"test-schema\".tickets) [numPartitions=1]",
+ desc = "Scan JDBCRelation(\"test-schema\".tickets) [numPartitions=1] " +
+ "[ticket_no#0] PushedFilters: [], ReadSchema:
struct<ticket_no:string>",
+ metrics = List(
+ SQLPlanMetric(
+ name = "number of output rows",
+ accumulatorId = 75,
+ metricType = "sum"
+ ),
+ SQLPlanMetric(
+ name = "JDBC query execution time",
+ accumulatorId = 35,
+ metricType = "nsTiming")))
+ val dotNode = planGraphNode.makeDotNode(Map.empty[Long, String])
+ val expectedDotNode = " 24 [id=\"node24\" labelType=\"html\" label=\"" +
+ "<br><b>Scan JDBCRelation(\\\"test-schema\\\".tickets)
[numPartitions=1]</b><br><br>\" " +
+ "tooltip=\"Scan JDBCRelation(\\\"test-schema\\\".tickets)
[numPartitions=1] [ticket_no#0] " +
+ "PushedFilters: [], ReadSchema: struct<ticket_no:string>\"];"
+
+ assertResult(expectedDotNode)(dotNode)
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]