Repository navigation
Conversation
…on (opensearch-project#5879) The SQL grammar's root rule (sqlStatement? SEMI? EOF) accepts input with no statement, so an empty, whitespace-only, comment-only or ";" query parsed successfully and AstStatementBuilder returned a null Statement. QueryPlanFactory then dereferenced it, and the response exposed the resulting NullPointerException. Make sqlStatement required in the root rule, as opensearch-project#5868 did for PPL. Such queries now fail in the v2 parser with a SyntaxCheckException, fall back to the legacy engine like any other v2 syntax error, and return its standard 400 syntax error. This also covers the unified-API SqlV2QueryParser, which threw a NullPointerException on the same input. Add sql and sql.explain REST API specs so the YAML REST test can call the SQL endpoints. Signed-off-by: Jialiang Liang <jiallian@amazon.com>
Decision LogRoot Cause: Approach (adopted from review): Alternatives Rejected:
Result: on Things to Watch:
|
PR Reviewer Guide 🔍(Review updated until commit 4ff7fa8)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to 4ff7fa8 Explore these optional code suggestions:
Previous suggestionsSuggestions up to commit bc88f54
Suggestions up to commit 403a3ad
Suggestions up to commit 62586d3
|
The Calcite engine only applies to PPL: QueryService.shouldUseCalcite returns isCalciteEnabled(settings) && queryType == QueryType.PPL. An empty SQL query is also rejected by the parser before QueryService is reached, so toggling plugins.calcite.enabled had no effect on these tests. Signed-off-by: Jialiang Liang <jiallian@amazon.com>
|
Persistent review updated to latest commit 403a3ad |
A query with no statement (empty, whitespace, comments or semicolons only) cannot run on the legacy engine either, so falling back only replaced the v2 parser's SyntaxCheckException with a misleading legacy error. Detect such input with the SQL lexer and return the v2 syntax error (400), as PPL does. Signed-off-by: Jialiang Liang <jiallian@amazon.com>
|
Persistent review updated to latest commit bc88f54 |
|
|
||
| root | ||
| : sqlStatement? SEMI? EOF | ||
| : sqlStatement SEMI? EOF |
There was a problem hiding this comment.
To simplify this, probably we can keep the question mark and throw a different exception (e.g., IllegalArgumentException) in visitRoot when sqlStatement is null to avoid fallback?
There was a problem hiding this comment.
Fixed. The grammar is reverted, and visitRoot now throws IllegalArgumentException("Query is empty"), which returns 400 without falling back to legacy.
Previously I was trying to align with the PPL exception type on it, but in SQL any SyntaxCheckException falls back to legacy, so matching PPL needed an extra empty-query check in the fallback path. Your suggested approach avoids that with a much smaller change.
Codecov Report✅ All modified and coverable lines are covered by tests. ❌ Your project check has failed because the head coverage (63.88%) is below the target coverage (99.00%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #5880 +/- ##
=========================================
Coverage 63.87% 63.88%
- Complexity 9091 9093 +2
=========================================
Files 962 962
Lines 41033 41036 +3
Branches 4668 4668
=========================================
+ Hits 26211 26214 +3
Misses 13944 13944
Partials 878 878
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Follow review feedback: keep the optional statement in the SQL root rule
and reject a root with no statement in AstStatementBuilder.visitRoot with
IllegalArgumentException("Query is empty"). IllegalArgumentException is
classified as a client error, so the request returns 400, and it is not a
SyntaxCheckException, so it does not fall back to the legacy engine.
This removes the grammar change, SQLSyntaxParser.hasNoStatement and the
fallback listener change, along with their tests. The api module's
SqlV2QueryParser uses the same AstStatementBuilder, so it now throws the
same exception instead of a NullPointerException.
Signed-off-by: Jialiang Liang <jiallian@amazon.com>
|
Persistent review updated to latest commit 4ff7fa8 |
Description
An empty SQL query (
{"query": ""}), or one that is only whitespace, only a comment, or only;, returned a 400 whose body exposed an internalNullPointerException(... because "statement" is null). This happened on_plugins/_sql,_plugins/_sql/_explainand?format=jdbc. Calcite is not involved: the v2 SQL path does not use it (Calcite applies to PPL only, seeQueryService.shouldUseCalcite).Root cause: the SQL grammar's root rule
sqlStatement? SEMI? EOFaccepts input with no statement, so parsing succeeds andAstStatementBuilderreturns anullStatement, whichQueryPlanFactory.createthen dereferences. This is the SQL counterpart of the PPL bug #5867.Fix:
AstStatementBuilder.visitRootthrowsIllegalArgumentException("Query is empty")when the root has no statement. The grammar is unchanged.Resulting error:
IllegalArgumentExceptionis a client error inRestSqlAction, so the request returns 400. It is not aSyntaxCheckException, soRestSQLQueryActiondoes not fall back to the legacy engine. Other syntax errors (e.g.SELEC 1) still fall back as before.The unified-API
SqlV2QueryParseruses the sameAstStatementBuilder, so it no longer throwsNullPointerException: Cannot invoke "Object.getClass()" because "statement" is nullon the same input. It now throws the sameIllegalArgumentException.Related Issues
Resolves #5879
PPL counterpart: #5867, fixed by #5868
Check List
--signoffor-s.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.