aboutsummaryrefslogtreecommitdiff
path: root/sql/catalyst
diff options
context:
space:
mode:
authorSean Zhong <seanzhong@databricks.com>2016-06-01 17:03:39 -0700
committerWenchen Fan <wenchen@databricks.com>2016-06-01 17:03:39 -0700
commitc8fb776d4a0134c47f90272c4bd5e4bba902aae5 (patch)
treeacf18d4e19a1559482d6dd8f268a36c06b9bcbbc /sql/catalyst
parent8640cdb836b4964e4af891d9959af64a2e1f304e (diff)
downloadspark-c8fb776d4a0134c47f90272c4bd5e4bba902aae5.tar.gz
spark-c8fb776d4a0134c47f90272c4bd5e4bba902aae5.tar.bz2
spark-c8fb776d4a0134c47f90272c4bd5e4bba902aae5.zip
[SPARK-15692][SQL] Improves the explain output of several physical plans by displaying embedded logical plan in tree style
## What changes were proposed in this pull request? Improves the explain output of several physical plans by displaying embedded logical plan in tree style Some physical plan contains a embedded logical plan, for example, `cache tableName query` maps to: ``` case class CacheTableCommand( tableName: String, plan: Option[LogicalPlan], isLazy: Boolean) extends RunnableCommand ``` It is easier to read the explain output if we can display the `plan` in tree style. **Before change:** Everything is messed in one line. ``` scala> Seq((1,2)).toDF().createOrReplaceTempView("testView") scala> spark.sql("cache table testView2 select * from testView").explain() == Physical Plan == ExecutedCommand CacheTableCommand testView2, Some('Project [*] +- 'UnresolvedRelation `testView`, None ), false ``` **After change:** ``` scala> spark.sql("cache table testView2 select * from testView").explain() == Physical Plan == ExecutedCommand : +- CacheTableCommand testView2, false : : +- 'Project [*] : : +- 'UnresolvedRelation `testView`, None ``` ## How was this patch tested? Manual test. Author: Sean Zhong <seanzhong@databricks.com> Closes #13433 from clockfly/verbose_breakdown_3_2.
Diffstat (limited to 'sql/catalyst')
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/QueryPlan.scala2
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/trees/TreeNode.scala10
2 files changed, 8 insertions, 4 deletions
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/QueryPlan.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/QueryPlan.scala
index d4447ca32d..6784c3ae1d 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/QueryPlan.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/QueryPlan.scala
@@ -264,7 +264,7 @@ abstract class QueryPlan[PlanType <: QueryPlan[PlanType]] extends TreeNode[PlanT
expressions.flatMap(_.collect {case e: SubqueryExpression => e.plan.asInstanceOf[PlanType]})
}
- override def innerChildren: Seq[PlanType] = subqueries
+ override protected def innerChildren: Seq[QueryPlan[_]] = subqueries
/**
* Canonicalized copy of this query plan.
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/trees/TreeNode.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/trees/TreeNode.scala
index d87e6c76ed..3ebd815dce 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/trees/TreeNode.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/trees/TreeNode.scala
@@ -424,9 +424,12 @@ abstract class TreeNode[BaseType <: TreeNode[BaseType]] extends Product {
*/
protected def stringArgs: Iterator[Any] = productIterator
+ private lazy val allChildren: Set[TreeNode[_]] = (children ++ innerChildren).toSet[TreeNode[_]]
+
/** Returns a string representing the arguments to this node, minus any children */
def argString: String = productIterator.flatMap {
- case tn: TreeNode[_] if containsChild(tn) => Nil
+ case tn: TreeNode[_] if allChildren.contains(tn) => Nil
+ case Some(tn: TreeNode[_]) if allChildren.contains(tn) => Nil
case tn: TreeNode[_] => s"${tn.simpleString}" :: Nil
case seq: Seq[BaseType] if seq.toSet.subsetOf(children.toSet) => Nil
case seq: Seq[_] => seq.mkString("[", ",", "]") :: Nil
@@ -467,9 +470,10 @@ abstract class TreeNode[BaseType <: TreeNode[BaseType]] extends Product {
}
/**
- * All the nodes that are parts of this node, this is used by subquries.
+ * All the nodes that should be shown as a inner nested tree of this node.
+ * For example, this can be used to show sub-queries.
*/
- protected def innerChildren: Seq[BaseType] = Nil
+ protected def innerChildren: Seq[TreeNode[_]] = Seq.empty
/**
* Appends the string represent of this node and its children to the given StringBuilder.