[SPARK-58098][SQL] Convert _LEGACY_ERROR_TEMP_0033 to an internal error#57218
[SPARK-58098][SQL] Convert _LEGACY_ERROR_TEMP_0033 to an internal error#57218LuciferYang wants to merge 2 commits into
Conversation
…_TEMP_0033 Rename the legacy error condition `_LEGACY_ERROR_TEMP_0033` to `STORED_AS_AND_STORED_BY_BOTH_SPECIFIED`. The branch in `AstBuilder.visitCreateFileFormat` that raises this error is unreachable during normal parsing: the grammar rule `createFileFormat` accepts either STORED AS or STORED BY but not both, and a duplicated clause is already rejected as `DUPLICATE_CLAUSES`. Since it can only be reached through an internal inconsistency, the new condition is defined as an internal error (SQLSTATE `XX000`), following the existing `UNEXPECTED_USE_OF_PARAMETER_MARKER` precedent, and no user-facing test is added.
MaxGekk
left a comment
There was a problem hiding this comment.
If it is an internal error, why can't you just throw SparkException.internalError?
Convert the legacy error condition `_LEGACY_ERROR_TEMP_0033` to a `SparkException.internalError` and remove it from `error-conditions.json`. The branch in `AstBuilder.visitCreateFileFormat` that raises this error is unreachable during normal parsing: the grammar rule `createFileFormat` accepts either STORED AS or STORED BY but not both, and a duplicated clause is already rejected as `DUPLICATE_CLAUSES`. Since it can only be reached through an internal inconsistency, it does not need a user-facing error condition. Note that `SparkException.internalError` has no overload that carries the parser context, so the `ParseException` position information (offending fragment, line/column) is no longer attached. This is acceptable here because the branch is unreachable from user queries.
|
Good point, done. I've switched it to One thing worth flagging: |
MaxGekk
left a comment
There was a problem hiding this comment.
LGTM. This implements the SparkException.internalError conversion from the earlier thread.
I verified the case _ branch is not reachable via any public API, not just "normal parsing":
visitCreateFileFormathas a single definition (AstBuilder.scala:5599) overriding the generated ANTLR visitor — no subclass (incl.SparkSqlParser) reimplements it.- Its only caller is
createFileFormatCtx.map(visitCreateFileFormat)(AstBuilder.scala:5779); the contexts come from the grammar rulecreateFileFormat : STORED AS fileFormat | STORED BY storageHandler(SqlBaseParser.g4:726-729), a strict alternation, so a singleCreateFileFormatContextcan never carry both children. - The statement-level "both clauses" case is caught earlier by
checkDuplicateClauses(ctx.createFileFormat, "STORED AS/BY", ctx)→DUPLICATE_CLAUSES(AstBuilder.scala:5733), before the visitor runs. AstBuilder/getSerdeInfoare internal, so there's no programmatic path that hands a synthetic context to the visitor.
So it can only fire on a violated grammar invariant — internalError is the right call, and dropping the parser position info has no user-facing impact. The removal is complete (no dangling _LEGACY_ERROR_TEMP_0033 references, alphabetical order preserved, sole caller updated) and consistent with the existing internalError precedent at QueryParsingErrors.scala:44.
|
+1, LGTM. Merging to master/4.x. |
### What changes were proposed in this pull request? Convert the legacy error condition `_LEGACY_ERROR_TEMP_0033` to a `SparkException.internalError` and remove it from `error-conditions.json`. ### Why are the changes needed? The error-conditions README disallows new `_LEGACY_ERROR_TEMP_*` entries and asks existing ones to be resolved. This resolves one of them. The condition is raised in `AstBuilder.visitCreateFileFormat`, in the branch where both `STORED AS` and `STORED BY` are present. That branch is not reachable from normal parsing: - The grammar rule `createFileFormat` is `STORED AS fileFormat | STORED BY storageHandler`, so one clause carries only one of the two. - Two clauses (`STORED AS ... STORED BY ...`) are rejected earlier by `checkDuplicateClauses` as `DUPLICATE_CLAUSES`. As it only signals an internal inconsistency, it does not need a user-facing error condition and is converted to an internal error, following precedents such as SPARK-42839. One trade-off: `SparkException.internalError` has no overload that carries the parser context, so the `ParseException` position information (offending fragment, line/column) is no longer attached. This is acceptable here because the branch is unreachable from user queries. ### Does this PR introduce _any_ user-facing change? No. The code path is unreachable from user queries, so the change is not observable in practice. ### How was this patch tested? `build/sbt "core/testOnly org.apache.spark.SparkThrowableSuite"` passes, covering the JSON validation gates (alphabetical ordering, mandatory SQLSTATE, round-trip). No test is added because the path is unreachable. ### Was this patch authored or co-authored using generative AI tooling? Generated-by: Claude Code (Opus 4.8) Closes #57218 from LuciferYang/assign-name-legacy-0033. Authored-by: YangJie <yangjie01@baidu.com> Signed-off-by: Max Gekk <max.gekk@gmail.com> (cherry picked from commit e33ac21) Signed-off-by: Max Gekk <max.gekk@gmail.com>
What changes were proposed in this pull request?
Convert the legacy error condition
_LEGACY_ERROR_TEMP_0033to aSparkException.internalErrorand remove it fromerror-conditions.json.Why are the changes needed?
The error-conditions README disallows new
_LEGACY_ERROR_TEMP_*entries and asks existing ones to be resolved. This resolves one of them.The condition is raised in
AstBuilder.visitCreateFileFormat, in the branch where bothSTORED ASandSTORED BYare present. That branch is not reachable from normal parsing:createFileFormatisSTORED AS fileFormat | STORED BY storageHandler, so one clause carries only one of the two.STORED AS ... STORED BY ...) are rejected earlier bycheckDuplicateClausesasDUPLICATE_CLAUSES.As it only signals an internal inconsistency, it does not need a user-facing error condition and is converted to an internal error, following precedents such as SPARK-42839.
One trade-off:
SparkException.internalErrorhas no overload that carries the parser context, so theParseExceptionposition information (offending fragment, line/column) is no longer attached. This is acceptable here because the branch is unreachable from user queries.Does this PR introduce any user-facing change?
No. The code path is unreachable from user queries, so the change is not observable in practice.
How was this patch tested?
build/sbt "core/testOnly org.apache.spark.SparkThrowableSuite"passes, covering the JSON validation gates (alphabetical ordering, mandatory SQLSTATE, round-trip). No test is added because the path is unreachable.Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Opus 4.8)