[SPARK-58945][SQL] Fix mismatched messageParameters keys that cause INTERNAL_ERROR - #58225
[SPARK-58945][SQL] Fix mismatched messageParameters keys that cause INTERNAL_ERROR#58225subhramit wants to merge 25 commits into
messageParameters keys that cause INTERNAL_ERROR#58225Conversation
…ir error templates Signed-off-by: subhramit <subhramit.bb@live.in>
…2Dialect Signed-off-by: subhramit <subhramit.bb@live.in>
…ERROR_TEMP_3070` Signed-off-by: subhramit <subhramit.bb@live.in>
…est style Signed-off-by: subhramit <subhramit.bb@live.in>
…tercepted earlier Signed-off-by: subhramit <subhramit.bb@live.in>
Signed-off-by: Subhramit Basu <subhramit.bb@live.in>
|
Thank you @subhramit! |
Thank you for the quick review :) I will be filing a small follow-up after this for SPARK-58946 (currently this doesn't surface because due to Update - filed as #58226. |
|
All parameter keys match their templates, and regression coverage is appropriate, added @cloud-fan to also take a look |
|
@uros-b this now has two approvals. |
|
@LuciferYang hey, adding you in case this can be merged as the PR has now reached page 5.
|
I will take a look at this PR during today's working hours. |
Sure, thank you! |
LuciferYang
left a comment
There was a problem hiding this comment.
Went through all six sites; the direction checks out and each rename matches its template. Since the old keys always failed to render, no caller could have been reading them, so the renames carry no compatibility risk.
Two things I would fold into this PR: the same mismatch is still open on CURSOR_OUTSIDE_SCRIPT, where ResolveCursors.scala:85 and CursorCommandUtils.scala:41 both pass a cursorName the template does not declare, and the new H2Dialect comment states the opposite of what the surrounding code shows. The rest of the comments are non-blocking.
Signed-off-by: subhramit <subhramit.bb@live.in>
Signed-off-by: subhramit <subhramit.bb@live.in>
Signed-off-by: subhramit <subhramit.bb@live.in>
Signed-off-by: subhramit <subhramit.bb@live.in>
Signed-off-by: subhramit <subhramit.bb@live.in>
Signed-off-by: subhramit <subhramit.bb@live.in>
Signed-off-by: subhramit <subhramit.bb@live.in>
|
Hi guys, I know everyone's quite busy, and I understand as I maintain multiple projects myself. |
|
Thank you @subhramit, I don't have any additional concerns here - but let's wait a bit more for @LuciferYang's re-review |
|
A sweep anchored on the |
Signed-off-by: subhramit <subhramit.bb@live.in>
Signed-off-by: subhramit <subhramit.bb@live.in>
Signed-off-by: subhramit <subhramit.bb@live.in>
Yep, had missed that one. fixed in the latest commit by wiring |
| checkError( | ||
| exception = parseException("c:['']"), | ||
| condition = "PARSE_SYNTAX_ERROR", | ||
| parameters = Map("error" -> "'[''']'", "hint" -> "")) |
There was a problem hiding this comment.
The new "invalid semi-structured extract path" test expects one extra single quote: for input c:[''], '' lexes as one empty STRING_LITERAL, ctx.path.getText is [''], so s"'$field'" yields '['']' (two inner quotes) while the test expects '[''']' (three). The catalyst CI job on the head commit already fails on exactly this test: parameters: expected Map(error -> '[''']', hint -> ) but got HashMap(hint -> , error -> '['']').
Changing the expectation to "'['']'" fixes it.
There was a problem hiding this comment.
fixed in 856cc11
Should have run it locally or looked at the ci. Thanks
There was a problem hiding this comment.
856cc11 fixes one of the two mismatches, but the test still fails on the new head's CI: the full old-CI failure reads checkError found 2 mismatch(es), and the second one, queryContext.length: expected 0 but got 1, is still there. The ParseException carries one SQL QueryContext by default (fragment c:[''], 0 to 5), while this checkError passes no queryContext, so it compares against an empty array and the lengths can never match.
Adding queryContext = Array(ExpectedContext("c:['']", 0, 5)) to the checkError call makes it pass. My earlier comment only looked at the parameters line and missed this one, sorry about that.
There was a problem hiding this comment.
Yes figured that, this is now fixed
Signed-off-by: subhramit <subhramit.bb@live.in>
|
Somehow the test still fails. Let me take a deeper look. |
Signed-off-by: subhramit <subhramit.bb@live.in>
|
One more reachable site of the same bug class, in Adding |
Signed-off-by: subhramit <subhramit.bb@live.in>
|
Signed-off-by: subhramit <subhramit.bb@live.in>
Signed-off-by: subhramit <subhramit.bb@live.in>
|
K8s integration test failed in https://github.com/subhramit/spark/actions/runs/33940800548/job/101240221054 but seemed unrelated to my changes, so re-triggered the CI with an empty commit. Edit - I am unsure why this is happening every time now:
|
Signed-off-by: subhramit <subhramit.bb@live.in>
Signed-off-by: subhramit <subhramit.bb@live.in>
Okay apparently this happened in other PRs as well and is indeed unrelated. See comment #58503 (comment). |
Signed-off-by: subhramit <subhramit.bb@live.in>
|
@LuciferYang CI is now green, could you take a final look? |
Closes SPARK-58945
Note that the following description was initially generated using GPT 5.4, and then edited by me.
What changes were proposed in this pull request?
This fixes several broken Spark error-reporting paths caused by mismatches between
messageParameterskeys and the placeholders declared inerror-conditions.json.The changes fall into two groups:
Fix Scala-side parameter key mismatches
sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala_LEGACY_ERROR_TEMP_2450: useclazzinstead ofinvalidClasssql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryExecutionErrors.scalaINVALID_PARAMETER_VALUE.EXTENSION: useinvalidValueinstead offileExtension/acceptableINVALID_WRITER_COMMIT_MESSAGE: usedetailinstead ofdetailssql/core/src/main/scala/org/apache/spark/sql/execution/streaming/state/StateStoreErrors.scalaSTATE_STORE_COLUMN_FAMILY_SCHEMA_INCOMPATIBLE: usecolFamilyName/oldSchema/newSchemasql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/ResolveCursors.scalaandsql/core/src/main/scala/org/apache/spark/sql/execution/command/v2/CursorCommandUtils.scalaCURSOR_OUTSIDE_SCRIPT: declare and populatecursorNameconsistentlysql/core/src/main/scala/org/apache/spark/sql/jdbc/H2Dialect.scalaTABLE_OR_VIEW_NOT_FOUND: add the missingsearchPathparameter using the shared empty-search-path rendering fromNoSuchItemExceptionHelper.formatSearchPath(Seq.empty), and fall back tooldNamewhentableNameis absent so missing-source rename errors render correctlysql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scalaPARSE_SYNTAX_ERROR: provide the requirederror/hintparameters for invalid semi-structured extract pathssql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/aggregate/ApproxCountDistinctForIntervals.scalaDATATYPE_MISMATCH.NON_FOLDABLE_INPUT: provide the missinginputExprparameterFix one duplicated JSON message template
common/utils/src/main/resources/error/error-conditions.json_LEGACY_ERROR_TEMP_3069and_LEGACY_ERROR_TEMP_3070had byte-identical message templates._LEGACY_ERROR_TEMP_3069is the reserved-column-name collision case and its message is correct._LEGACY_ERROR_TEMP_3070is the unrecognized file metadata field fallback, and its Scala call site (Map("field" -> field.toString)) was already correct.This PR fixes only the template for
_LEGACY_ERROR_TEMP_3070, restoring the pre-error class-migration wording:Unrecognized file metadata field: <field>. This is the text the branch threw before the error-class migration in SPARK-46351, still visible at thev3.5.0tag.A minimal repro for one affected path is:
Before this change, that path fails during message rendering and surfaces
INTERNAL_ERRORinstead ofINVALID_PARAMETER_VALUE.EXTENSION.Why are the changes needed?
Spark's
StringSubstitutordefaults toenableUndefinedVariableException = true, so an unresolved placeholder throwsIllegalArgumentException, whichErrorClassesJSONReaderconverts intoSparkException.internalError.Error messages are rendered eagerly when constructing many exceptions. The relevant exception constructors call
SparkThrowableHelper.getMessageduring construction (example). When substitution fails, the intended exception instance is never created, so the affected paths returnINTERNAL_ERRORin place of the actual diagnosis.These are user-visible diagnostics bugs rather than behavior changes in the main execution path.
One of the fixed paths is not demonstrated by an end-to-end repro today.
stateStoreColumnFamilyMismatchcurrently has no callers, so that path is latent. It would have failed during message construction before this fix, so the factory is covered directly by a unit test. This PR only fixes its parameter mapping so the path is correct if thetransformWithStateside wires it up in follow-up work.The
H2Dialect.scala:230change is covered through the directrenameTable(...)API path. Missing-tableloadTableis intercepted earlier byJDBCRDD.resolveTable(...), so that path does not exercise the dialect branch.For
_LEGACY_ERROR_TEMP_3070the failure mode differs: the Scala call site was already correct, but the JSON template was duplicated from_LEGACY_ERROR_TEMP_3069during the error-class migration in SPARK-46351, so the fallback reports a reserved-column-name collision that never occurred.Does this PR introduce any user-facing change?
Yes.
This PR fixes user-facing error reporting for the currently reachable affected paths on master, and also fixes one currently latent path.
Examples:
extensionvalues now reportINVALID_PARAMETER_VALUE.EXTENSIONinstead of failing during message construction.INVALID_WRITER_COMMIT_MESSAGEwith the intended detail text.CURSOR_OUTSIDE_SCRIPTnow reports the cursor name in the diagnostic._LEGACY_ERROR_TEMP_3070now reportsUnrecognized file metadata field: <field>instead of the unrelated reserved-column-name message.The H2 dialect change is a correctness fix in the JDBC classification path and is covered through the direct
renameTable(...)API path. The state store fix is latent today becausestateStoreColumnFamilyMismatchcurrently has no callers.This does not change the semantics of the underlying operations. It fixes the diagnostics that Spark surfaces when those error paths are hit.
How was this patch tested?
Added/updated regression tests:
QueryCompilationErrorsSuiteQueryExecutionErrorsSuiteJDBCTableCatalogSuiteFileSourceCustomMetadataStructSuiteCursorCommandUtilsSuiteSqlScriptingCursorE2eSuiteStateStoreErrorsSuiteExpressionParserSuiteApproxCountDistinctForIntervalsSuiteExecuted:
and all of them passed.
Also performed manual repro -
main:fa6f713:Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude Opus 5 + GPT-5.4 (Zed coding agent) + manually driven, and touched up in IntelliJ IDEA