-
Notifications
You must be signed in to change notification settings - Fork 28.6k
[SPARK-45516][CONNECT] Include QueryContext in SparkThrowable proto message #43352
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2869,6 +2869,59 @@ class FetchErrorDetailsResponse(google.protobuf.message.Message): | |
self, oneof_group: typing_extensions.Literal["_file_name", b"_file_name"] | ||
) -> typing_extensions.Literal["file_name"] | None: ... | ||
|
||
class QueryContext(google.protobuf.message.Message): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. qq; could we do this in Python client too? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not yet if I understand correctly. @gatorsmile has some concern about whether exposing QueryContext in the PySpark Exception APIs makes sense for non-sql PySpark exceptions. There is some ongoing discussion for this. |
||
"""QueryContext defines the schema for the query context of a SparkThrowable. | ||
It helps users understand where the error occurs while executing queries. | ||
""" | ||
|
||
DESCRIPTOR: google.protobuf.descriptor.Descriptor | ||
|
||
OBJECT_TYPE_FIELD_NUMBER: builtins.int | ||
OBJECT_NAME_FIELD_NUMBER: builtins.int | ||
START_INDEX_FIELD_NUMBER: builtins.int | ||
STOP_INDEX_FIELD_NUMBER: builtins.int | ||
FRAGMENT_FIELD_NUMBER: builtins.int | ||
object_type: builtins.str | ||
"""The object type of the query which throws the exception. | ||
If the exception is directly from the main query, it should be an empty string. | ||
Otherwise, it should be the exact object type in upper case. For example, a "VIEW". | ||
""" | ||
object_name: builtins.str | ||
"""The object name of the query which throws the exception. | ||
If the exception is directly from the main query, it should be an empty string. | ||
Otherwise, it should be the object name. For example, a view name "V1". | ||
""" | ||
start_index: builtins.int | ||
"""The starting index in the query text which throws the exception. The index starts from 0.""" | ||
stop_index: builtins.int | ||
"""The stopping index in the query which throws the exception. The index starts from 0.""" | ||
fragment: builtins.str | ||
"""The corresponding fragment of the query which throws the exception.""" | ||
def __init__( | ||
self, | ||
*, | ||
object_type: builtins.str = ..., | ||
object_name: builtins.str = ..., | ||
start_index: builtins.int = ..., | ||
stop_index: builtins.int = ..., | ||
fragment: builtins.str = ..., | ||
) -> None: ... | ||
def ClearField( | ||
self, | ||
field_name: typing_extensions.Literal[ | ||
"fragment", | ||
b"fragment", | ||
"object_name", | ||
b"object_name", | ||
"object_type", | ||
b"object_type", | ||
"start_index", | ||
b"start_index", | ||
"stop_index", | ||
b"stop_index", | ||
], | ||
) -> None: ... | ||
|
||
class SparkThrowable(google.protobuf.message.Message): | ||
"""SparkThrowable defines the schema for SparkThrowable exceptions.""" | ||
|
||
|
@@ -2893,18 +2946,30 @@ class FetchErrorDetailsResponse(google.protobuf.message.Message): | |
|
||
ERROR_CLASS_FIELD_NUMBER: builtins.int | ||
MESSAGE_PARAMETERS_FIELD_NUMBER: builtins.int | ||
QUERY_CONTEXTS_FIELD_NUMBER: builtins.int | ||
error_class: builtins.str | ||
"""Succinct, human-readable, unique, and consistent representation of the error category.""" | ||
@property | ||
def message_parameters( | ||
self, | ||
) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: | ||
"""message parameters for the error framework.""" | ||
"""The message parameters for the error framework.""" | ||
@property | ||
def query_contexts( | ||
self, | ||
) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[ | ||
global___FetchErrorDetailsResponse.QueryContext | ||
]: | ||
"""The query context of a SparkThrowable.""" | ||
def __init__( | ||
self, | ||
*, | ||
error_class: builtins.str | None = ..., | ||
message_parameters: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., | ||
query_contexts: collections.abc.Iterable[ | ||
global___FetchErrorDetailsResponse.QueryContext | ||
] | ||
| None = ..., | ||
) -> None: ... | ||
def HasField( | ||
self, | ||
|
@@ -2921,6 +2986,8 @@ class FetchErrorDetailsResponse(google.protobuf.message.Message): | |
b"error_class", | ||
"message_parameters", | ||
b"message_parameters", | ||
"query_contexts", | ||
b"query_contexts", | ||
], | ||
) -> None: ... | ||
def WhichOneof( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, this should actually fail after #43334 PR because
DataFrameQueryContext
throws an exception now (https://github.com/apache/spark/pull/43334/files#diff-b3bc05fec45cd951053b2876c71c7730b63789cb4336a7537a6654c724db3241R586-R589).Seems like we miss this information Spark Connect client sides for now so it seems working .. but we should carry this context for DataFrame operations ..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MaxGekk I think there's a bug not only here but without Spark Connect.
It doesn't contain
QueryContext
from #43334 ..Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, there are three issues. TL;DR:
There are many places that does not provide
Origin
that containsQueryContext
atQueryCompilationErrors
. So theQueryContext
is often missing (e.g., the case above). cc @MaxGekk.
Origin.context
is being directly used on Executor side. e.g.,origin.context
atDivideYMInterval
. This seems wrongly returningSQLQueryContext
for DataFrame operations (from Executor side) in Spark Connect server because we do not callwithOrigin
there. That's why this specific code did not throw an exception from https://github.com/apache/spark/pull/43334/files#diff-b3bc05fec45cd951053b2876c71c7730b63789cb4336a7537a6654c724db3241R586-R589 because it has never beenDataFrameContext
cc @heyihong @juliuszsompolskiThe current logic in
ErrorUtils.scala
should handle the case ofDataFrameQueryContext
e.g.,DataFrameQueryContext.stopIndex()
will throw an exception. Should we:DataFrameQueryContext.stopIndex()
instead of throwing an exception? @MaxGekkThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you mean client? Server side stacktrace is not interesting to users to understand their own code mistakes.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a mistake. I updated my comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either setting a default value or making the protobuf field optional should work. It depends on the semantic of
DataFrameQueryContext.stopIndex()
.cc: @MaxGekk
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make sure we fix this.