Skip to content

Conversation

@liancheng
Copy link
Contributor

When examining plans of complex queries with multiple joins, a pain point of mine is that, it's hard to immediately see the sibling node of a specific query plan node. This PR adds tree lines for the tree string of a TreeNode, so that the result can be visually more intuitive.

@liancheng
Copy link
Contributor Author

For example, the following snippet

val path = "file:///tmp/parquet/unsafe"
(sqlContext range 10 coalesce 1).write mode "overwrite" parquet path
sqlContext.read parquet path registerTempTable "u"
sqlContext.sql(
  """SELECT COUNT(*)
    |FROM (
    |  SELECT x.id FROM u x JOIN u y ON x.id = y.id
    |) a
    |JOIN (
    |  SELECT * FROM u WHERE id < 7
    |) b
    |WHERE a.id = b.id
  """.stripMargin
) explain true

gives the following query plan explanation, which can be (arguably) more intuitive:

...

== Analyzed Logical Plan ==
_c0: bigint
Aggregate [(count(1),mode=Complete,isDistinct=false) AS _c0#23L]
+- Filter (id#0L = id#22L)
   +- Join Inner, None
      :- Subquery a
      :  +- Project [id#0L]
      :     +- Join Inner, Some((id#0L = id#21L))
      :        :- Subquery x
      :        :  +- Subquery u
      :        :     +- Relation[id#0L] ParquetRelation[file:/tmp/parquet/unsafe]
      :        +- Subquery y
      :           +- Subquery u
      :              +- Relation[id#21L] ParquetRelation[file:/tmp/parquet/unsafe]
      +- Subquery b
         +- Project [id#22L]
            +- Filter (id#22L < cast(7 as bigint))
               +- Subquery u
                  +- Relation[id#22L] ParquetRelation[file:/tmp/parquet/unsafe]

...

The reason why ":" is chosen instead of "|" is that, "|" doesn't play well with the following pattern (which is used extensively in Spark SQL), because "|" is the default margin character in Scala.

"""...
  |plan.treeString
  |...
""".stripMargin

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this may be arguably more readable:

lastChildren.init.map { isLast =>
  if (isLast) "   " else ":  "
}.mkString + (if (lastChildren.last) "+- " else ":- ")

@cloud-fan
Copy link
Contributor

This is pretty cool, thanks! LGTM

@liancheng
Copy link
Contributor Author

@cloud-fan Thanks! Comments addressed.

@SparkQA
Copy link

SparkQA commented Dec 2, 2015

Test build #47053 has finished for PR 10099 at commit 90b46d9.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@liancheng liancheng force-pushed the prettier-tree-string branch from 10eb09e to 31a1c22 Compare December 2, 2015 12:38
@SparkQA
Copy link

SparkQA commented Dec 2, 2015

Test build #47062 has finished for PR 10099 at commit 10eb09e.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@SparkQA
Copy link

SparkQA commented Dec 2, 2015

Test build #47063 has finished for PR 10099 at commit 31a1c22.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@yhuai
Copy link
Contributor

yhuai commented Dec 2, 2015

Merging to master and branch 1.6.

asfgit pushed a commit that referenced this pull request Dec 2, 2015
When examining plans of complex queries with multiple joins, a pain point of mine is that, it's hard to immediately see the sibling node of a specific query plan node. This PR adds tree lines for the tree string of a `TreeNode`, so that the result can be visually more intuitive.

Author: Cheng Lian <[email protected]>

Closes #10099 from liancheng/prettier-tree-string.

(cherry picked from commit a1542ce)
Signed-off-by: Yin Huai <[email protected]>
@asfgit asfgit closed this in a1542ce Dec 2, 2015
@liancheng liancheng deleted the prettier-tree-string branch December 2, 2015 23:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants