Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SPARK-45826][SQL] Add a SQL config for stack traces in DataFrame query context #43695

Closed
wants to merge 6 commits into from

Conversation

MaxGekk
Copy link
Member

@MaxGekk MaxGekk commented Nov 7, 2023

What changes were proposed in this pull request?

In the PR, I propose to add new SQL config spark.sql.stackTracesInDataFrameContext which defines how many non-Spark stack traces should be captured into DataFrame query context. By default, the config is set to 1.

Why are the changes needed?

To improve user experience with Spark SQL. When users troubleshoot an issue, they might need more stack traces in the DataFrame context. For example:

scala> spark.conf.set("spark.sql.ansi.enabled", true)
scala> spark.conf.set("spark.sql.stackTracesInDataFrameContext", 3)
scala> spark.range(1).select(lit(1) / lit(0)).collect()
org.apache.spark.SparkArithmeticException: [DIVIDE_BY_ZERO] Division by zero. Use `try_divide` to tolerate divisor being 0 and return NULL instead. If necessary set "spark.sql.ansi.enabled" to "false" to bypass this error. SQLSTATE: 22012
== DataFrame ==
"div" was called from
<init>(<console>:1)
<init>(<console>:16)
.<clinit>(<console>:1)

Does this PR introduce any user-facing change?

No, it doesn't change the default behaviour.

How was this patch tested?

By running the modified test suite:

$ build/sbt "test:testOnly *QueryContextSuite"

Was this patch authored or co-authored using generative AI tooling?

No.

@github-actions github-actions bot added the SQL label Nov 7, 2023
@MaxGekk MaxGekk changed the title [WIP][SQL] Add a SQL config for extra traces in Origin [WIP][SPARK-45826][SQL] Add a SQL config for extra traces in Origin Nov 7, 2023
@MaxGekk MaxGekk changed the title [WIP][SPARK-45826][SQL] Add a SQL config for extra traces in Origin [SPARK-45826][SQL] Add a SQL config for extra traces in Origin Nov 8, 2023
@MaxGekk MaxGekk marked this pull request as ready for review November 8, 2023 13:44
"When it is set to 0, captured one Spark traces and a followed non-Spark trace.")
.version("4.0.0")
.intConf
.checkValue(_ >= 0, "The number of extra thread traces must be non-negative.")
Copy link
Contributor

Choose a reason for hiding this comment

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

should it be > 0?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is extra traces, see the config description:

When it is set to 0, captured one Spark traces and a followed non-Spark trace.

For instance
Screenshot 2023-11-01 at 21 29 18
when it is 0, we return 4 and 5
when it is 1, we return 4, 5, 6

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm a bit confused.
Intuitively, I feel that 0 should represent the absence of non-Spark trace.

Copy link
Member Author

Choose a reason for hiding this comment

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

Intuitively, I feel that 0 should represent the absence of non-Spark trace.

Actually, it works in this way. Let me modify the config and PR description. The slice method excludes the until index.

Copy link
Contributor

Choose a reason for hiding this comment

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

I feel that:
default 1: this is consistent with before.
The number of extraOriginTraces should consistent with the number of non-Spark trace size.
Then we use > 0 as the constraint.

@cloud-fan
Copy link
Contributor

Can we put a real example in the PR description?

dongjoon-hyun pushed a commit that referenced this pull request Nov 12, 2023
… context

### What changes were proposed in this pull request?
In the PR, I propose to include all available stack traces in DataFrame context to the `callSite` field and apparently to the `summary`. For now, DataFrame context contains only one item of stack trace, but later we'll add a config to control the number of items in stack traces (see #43695).

### Why are the changes needed?
To improve user experience with Spark SQL while debugging some issue. Users can see all available stack trace, and see from where the issue comes in user code from.

### Does this PR introduce _any_ user-facing change?
No, should not. Even if user's code parses the summary.

### How was this patch tested?
By running new test suite:
```
$ build/sbt "test:testOnly *QueryContextSuite"
```

### Was this patch authored or co-authored using generative AI tooling?
No.

Closes #43758 from MaxGekk/output-stack-trace.

Authored-by: Max Gekk <max.gekk@gmail.com>
Signed-off-by: Dongjoon Hyun <dhyun@apple.com>
@cloud-fan
Copy link
Contributor

Can we show the impact to the real error message, instead of val ctx = try { df.select(explode($"*")) } catch { case e: AnalysisException => e.context.head }?

@MaxGekk MaxGekk changed the title [SPARK-45826][SQL] Add a SQL config for extra traces in Origin [SPARK-45826][SQL] Add a SQL config for stack traces in DataFrame query context Nov 25, 2023
@MaxGekk
Copy link
Member Author

MaxGekk commented Nov 25, 2023

Can we show the impact to the real error message

@cloud-fan I added an example, please, take a look at the PR.

@cloud-fan
Copy link
Contributor

@MaxGekk not quite related in this PR, but what if the expression creation is different from the df creation? like

val divCol = lit(1) / lit(0)
spark.range(1).select(divCol).collect()

@MaxGekk
Copy link
Member Author

MaxGekk commented Nov 26, 2023

@cloud-fan Quite the same:

scala> val divCol = lit(1) / lit(0)
val divCol: org.apache.spark.sql.Column = `/`(1, 0)

scala> spark.range(1).select(divCol).collect()
org.apache.spark.SparkArithmeticException: [DIVIDE_BY_ZERO] Division by zero. Use `try_divide` to tolerate divisor being 0 and return NULL instead. If necessary set "spark.sql.ansi.enabled" to "false" to bypass this error. SQLSTATE: 22012
== DataFrame ==
"div" was called from
<init>(<console>:1)
<init>(<console>:15)
.<clinit>(<console>:1)

but when I create it in an object:

scala> object Obj1 {
     | val divCol = lit(1) / lit(0)
     | }
object Obj1

scala> spark.range(1).select(Obj1.divCol).collect()
org.apache.spark.SparkArithmeticException: [DIVIDE_BY_ZERO] Division by zero. Use `try_divide` to tolerate divisor being 0 and return NULL instead. If necessary set "spark.sql.ansi.enabled" to "false" to bypass this error. SQLSTATE: 22012
== DataFrame ==
"div" was called from
Obj1$.<init>(<console>:2)
Obj1$lzycompute$1(<console>:1)
Obj1(<console>:1)

@MaxGekk
Copy link
Member Author

MaxGekk commented Nov 26, 2023

Merging to master. Thank you, @cloud-fan and @beliefer for review.

@MaxGekk MaxGekk closed this in d30c9a9 Nov 26, 2023
Copy link
Contributor

@beliefer beliefer left a comment

Choose a reason for hiding this comment

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

late LGTM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
3 participants