Skip to content

Conversation

@sarutak
Copy link
Member

@sarutak sarutak commented Jul 27, 2019

DebugExec does not implement doExecuteBroadcast and doExecuteColumnar so we can't debug broadcast or columnar related query.

One example for broadcast is here.

val df1 = Seq(1, 2, 3).toDF
val df2 = Seq(1, 2, 3).toDF
val joined = df1.join(df2, df1("value") === df2("value"))
joined.debug()

java.lang.UnsupportedOperationException: Debug does not implement doExecuteBroadcast
...

Another for columnar is here.

val df = Seq(1, 2, 3).toDF
df.persist
df.debug()

java.lang.IllegalStateException: Internal Error class org.apache.spark.sql.execution.debug.package$DebugExec has column support mismatch:
...

How was this patch tested?

Additional test cases in DebuggingSuite.

@SparkQA
Copy link

SparkQA commented Jul 27, 2019

Test build #108253 has finished for PR 25274 at commit 6fd6260.

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

val rightDF = spark.range(10)
val leftDF = spark.range(10)
val joinedDF = leftDF.join(rightDF, leftDF("id") === rightDF("id"))
Try {
Copy link
Member

@maropu maropu Jul 28, 2019

Choose a reason for hiding this comment

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

How about checking the actual output like this instead of using Try?

    assert(joinedDF.queryExecution.sparkPlan.collect { case _: BroadcastHashJoinExec => true }.nonEmpty)
    val output = new java.io.ByteArrayOutputStream()
    Console.withOut(output) {
      joinedDF.debug()
    }
    assert(output.toString.contains("BroadcastHashJoin"))

Copy link
Member Author

@sarutak sarutak Jul 28, 2019

Choose a reason for hiding this comment

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

Thanks for the comment. I changed test-cases added to compare expected result to actual one using Console.withOut . But I think it's good to still handle exceptions for better error message when test-cases fail.
To do so, it's easy for us to identify which test-case fails (line number appears on the top of error message).

[info] - SPARK-28537: DebugExec cannot debug broadcast or columnar related queries *** FAILED *** (89 milliseconds)
[info]   debug() for broadcast failed with exception (DebuggingSuite.scala:76)
[info]   org.scalatest.exceptions.TestFailedException:
[info]   at org.scalatest.Assertions.newAssertionFailedException(Assertions.scala:528)
[info]   at org.scalatest.Assertions.newAssertionFailedException$(Assertions.scala:527)
[info]   at org.scalatest.FunSuite.newAssertionFailedException(FunSuite.scala:1560)

@SparkQA
Copy link

SparkQA commented Jul 28, 2019

Test build #108269 has finished for PR 25274 at commit 8ee28f5.

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

subtree.contains("Range") && code.contains("Object[]")})
}

test("SPARK-28537: DebugExec cannot debug broadcast or columnar related queries") {
Copy link
Member

Choose a reason for hiding this comment

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

IMO this is of improvements for debugging, so we don't need the prefix. cc: @dongjoon-hyun

Copy link
Member

Choose a reason for hiding this comment

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

or -> and in the title.

Copy link
Member

Choose a reason for hiding this comment

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

It seems that @sarutak reported this issue as a BUG.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think this is a BUG.

| id LongType: {}
|""".stripMargin))
} catch {
case e: Throwable => fail("debug() for columnar failed with exception", e)
Copy link
Member

@maropu maropu Jul 28, 2019

Choose a reason for hiding this comment

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

case NonFatal(e) =>


val exprId = df.queryExecution.executedPlan.output.head.toString
val output = captured.toString()
assert(output.contains(
Copy link
Member

Choose a reason for hiding this comment

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

For these kinds of tests, substring matching seems to be better than exact matching.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll follow the manner in ExplainSuite.

Copy link
Member

@maropu maropu left a comment

Choose a reason for hiding this comment

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

LGTM except for minor comments.

@SparkQA
Copy link

SparkQA commented Jul 29, 2019

Test build #108316 has finished for PR 25274 at commit 2685272.

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

@maropu
Copy link
Member

maropu commented Jul 30, 2019

cc: @dongjoon-hyun

@sarutak
Copy link
Member Author

sarutak commented Aug 4, 2019

@dongjoon-hyun Do you have any feedbacks?

|== Range (0, 10, step=1, splits=2) ==
|Tuples output: 0
| id LongType: {}""".stripMargin))
} catch {
Copy link
Contributor

Choose a reason for hiding this comment

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

why do we need this catch? the test would fail anyway

Copy link
Member Author

Choose a reason for hiding this comment

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

It's for better error message.
With catch, we can identify which assertion fails easily.
But if we split test cases, I think we can remove try/catch

|Tuples output: 0
| id LongType: {}
|""".stripMargin))
} catch {
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

case NonFatal(e) => fail("debug() for broadcast failed with exception", e)
}

val df = spark.range(5)
Copy link
Contributor

Choose a reason for hiding this comment

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

can we split this into 2 different tests?

Copy link
Contributor

@mgaido91 mgaido91 left a comment

Choose a reason for hiding this comment

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

LGTM apart from few comments


val output = captured.toString()replaceAll ("#\\d+", "#x")
assert(output.contains(
s"""== InMemoryTableScan [id#xL] ==
Copy link
Contributor

Choose a reason for hiding this comment

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

nit:

Suggested change
s"""== InMemoryTableScan [id#xL] ==
"""== InMemoryTableScan [id#xL] ==

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh... I forgot to remove it.

df.debug()
}

val output = captured.toString()replaceAll ("#\\d+", "#x")
Copy link
Contributor

Choose a reason for hiding this comment

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

nit:

Suggested change
val output = captured.toString()replaceAll ("#\\d+", "#x")
val output = captured.toString().replaceAll("#\\d+", "#x")

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks! What an embarrassing mistake...


test("SPARK-28537: DebugExec cannot debug columnar related queries") {
val df = spark.range(5)
df.persist()
Copy link
Contributor

Choose a reason for hiding this comment

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

shall we unpersist this?

@SparkQA
Copy link

SparkQA commented Aug 4, 2019

Test build #108624 has finished for PR 25274 at commit ee1c26f.

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

@SparkQA
Copy link

SparkQA commented Aug 4, 2019

Test build #108626 has finished for PR 25274 at commit 46c6598.

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

@maropu
Copy link
Member

maropu commented Aug 5, 2019

Thanks! Merged to master.
Thanks all for your work! @sarutak @mgaido91 @kiszk

@maropu maropu closed this Aug 5, 2019
@HyukjinKwon
Copy link
Member

Hmmm .. seems this commit causes the test failure:

https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/108687/
https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/108688/
https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/108693/

There are three consecutive builds being failed and it's failed in my local too.

@HyukjinKwon
Copy link
Member

seems 03e3006 was conflicted with this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants