Integrate SQL REST endpoint with analytics engine path#5317
Integrate SQL REST endpoint with analytics engine path#5317ahkcs wants to merge 10 commits intofeature/mustang-ppl-integrationfrom
Conversation
PR Code Analyzer ❗AI-powered 'Code-Diff-Analyzer' found issues on commit 7125fb6.
The table above displays the top 10 most important findings. Pull Requests Author(s): Please update your Pull Request according to the report above. Repository Maintainer(s): You can Thanks. |
PR Reviewer Guide 🔍(Review updated until commit a91d349)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to a91d349 Explore these optional code suggestions:
Previous suggestionsSuggestions up to commit 7b63b49
Suggestions up to commit 38710ef
|
38710ef to
7b63b49
Compare
|
Persistent review updated to latest commit 7b63b49 |
7b63b49 to
a91d349
Compare
|
Persistent review updated to latest commit a91d349 |
749d5e8 to
a69620e
Compare
4945d32 to
c28081c
Compare
integ-test/src/test/java/org/opensearch/sql/sql/AnalyticsSQLExplainIT.java
Outdated
Show resolved
Hide resolved
plugin/src/main/java/org/opensearch/sql/plugin/rest/RestUnifiedQueryAction.java
Outdated
Show resolved
Hide resolved
plugin/src/main/java/org/opensearch/sql/plugin/rest/RestUnifiedQueryAction.java
Outdated
Show resolved
Hide resolved
| * org.opensearch.sql.plugin.transport.TransportPPLQueryResponse} as the transport response type | ||
| * since both PPL and SQL share the same JSON response format. | ||
| */ | ||
| public void executeSql( |
There was a problem hiding this comment.
Why we need separate execute and explain logic for SQL path?
There was a problem hiding this comment.
Good point, removed the duplicate methods. SQL and PPL now share the same execute() and explain(). For SQL we pass profiling=false and ExplainMode.STANDARD since SQLQueryRequest doesn't have these fields yet — should we add them to SQLQueryRequest or is this fine for now?
integ-test/src/test/java/org/opensearch/sql/sql/AnalyticsSQLExplainIT.java
Outdated
Show resolved
Hide resolved
| } | ||
|
|
||
| @Test | ||
| public void testExplainSelectStar() throws IOException { |
There was a problem hiding this comment.
Could you also check EXPLAIN statement? It's supported by Calcite SQL, e.g., EXPLAIN PLAN FOR ... Ref: https://calcite.apache.org/docs/reference.html
There was a problem hiding this comment.
Investigated — EXPLAIN PLAN FOR is parsed by Calcite as a SqlExplain node, but SqlToRelConverter.convertQueryRecursive() doesn't handle it (throws AssertionError("not a query: ...") in the default case). Calcite treats EXPLAIN as a meta-statement handled at the JDBC layer (CalcitePrepareImpl), not at the SqlToRelConverter level.
To support it, we'd need to detect SqlExplain in CalciteNativeStrategy.plan(), unwrap the inner query, plan it, and return the plan as a formatted result. However, the resulting plan would be identical to what
/_plugins/_sql/_explain already returns for the same query — the only difference is the response format (EXPLAIN PLAN FOR returns the plan as a query result row, /_explain returns it as a JSON explain response)
Do we want to support EXPLAIN statement?
There was a problem hiding this comment.
Error log:
curl -s -X POST localhost:9200/_plugins/_sql -H 'Content-Type: application/json' -d '{"query": "EXPLAIN PLAN FOR SELECT * FROM parquet_logs"}'
{
"error": {
"reason": "Invalid SQL query",
"details": "Query must start with SELECT, DELETE, SHOW or DESCRIBE: EXPLAIN PLAN FOR SELECT * FROM parquet_logs",
"type": "SQLFeatureNotSupportedException"
},
"status": 400
}%
|
|
||
| // Route to analytics engine for non-Lucene (e.g., Parquet-backed) indices. | ||
| // The router returns true and sends the response directly if it handled the request. | ||
| if (analyticsRouter != null) { |
There was a problem hiding this comment.
just wonder analyticsRouter can be null? Is this implementation different from PPL path?
There was a problem hiding this comment.
Good point — analyticsRouter is always provided. Removed the no-arg constructor and null check
The implementation differs from PPL because RestSqlAction is in the legacy module which can't depend on plugin module, so we can't inject RestUnifiedQueryAction directly like PPL does in TransportPPLQueryAction. The BiFunction bridges the module boundary — it's created in SQLPlugin (plugin module) where RestUnifiedQueryAction is visible, then passed to RestSqlAction (legacy module).
There was a problem hiding this comment.
Got it. I think we may want to enable profiling, at least for unified SQL path later. @penghuo
legacy/src/main/java/org/opensearch/sql/legacy/plugin/RestSqlAction.java
Outdated
Show resolved
Hide resolved
Add SQL query routing through the analytics engine for Parquet-backed indices. SQL queries targeting "parquet_*" indices are routed to RestUnifiedQueryAction via the unified query pipeline (Calcite SQL parser -> UnifiedQueryPlanner -> AnalyticsExecutionEngine). Changes: - Add SqlNode table extraction in RestUnifiedQueryAction.extractIndexName() to support SQL query routing (handles SqlSelect -> SqlIdentifier) - Add executeSql() and explainSql() methods in RestUnifiedQueryAction for SQL queries (parallel to existing PPL execute/explain) - Add analytics routing in RestSqlAction via optional BiFunction router that checks isAnalyticsIndex before delegating to SQLService - Wire the router in SQLPlugin.createSqlAnalyticsRouter() - Non-analytics SQL queries fall through to the existing V2 engine - Add AnalyticsSQLIT integration tests: SELECT *, column projection, explain, non-parquet fallback, syntax error handling Resolves: #5248 Signed-off-by: Kai Huang <ahkcs@amazon.com>
c28081c to
5c25195
Compare
Signed-off-by: Kai Huang <ahkcs@amazon.com>
Signed-off-by: Kai Huang <ahkcs@amazon.com>
Signed-off-by: Kai Huang <ahkcs@amazon.com>
Signed-off-by: Kai Huang <ahkcs@amazon.com>
Signed-off-by: Kai Huang <ahkcs@amazon.com>
analyticsRouter is always provided — only one caller exists (SQLPlugin.getRestHandlers). Remove the backward-compatible no-arg constructor and the null check. Signed-off-by: Kai Huang <ahkcs@amazon.com>
plugin/src/main/java/org/opensearch/sql/plugin/rest/RestUnifiedQueryAction.java
Outdated
Show resolved
Hide resolved
b790bcb to
aacb418
Compare
Restore original logging (query anonymization, explain fallback) that was lost when the fallback logic was inlined into the analytics router lambda. Signed-off-by: Kai Huang <ahkcs@amazon.com>
Replace instanceof checks with SqlTableNameExtractor visitor, consistent with how PPL uses AbstractNodeVisitor for index name extraction. Signed-off-by: Kai Huang <ahkcs@amazon.com>
Signed-off-by: Kai Huang <ahkcs@amazon.com>
Summary
parquet_*indices are routed toRestUnifiedQueryActionvia the unified query pipeline (Calcite SQL parser → UnifiedQueryPlanner → AnalyticsExecutionEngine)Changes
SqlNodetable extraction inRestUnifiedQueryAction.extractIndexName()for SQL routingexecuteSql()andexplainSql()methods inRestUnifiedQueryActionRestSqlActionvia optionalBiFunctionrouterSQLPlugin.createSqlAnalyticsRouter()AnalyticsSQLITintegration testsResolves step 3: #5248