diff --git a/api/src/main/java/org/opensearch/sql/api/UnifiedQueryPlanner.java b/api/src/main/java/org/opensearch/sql/api/UnifiedQueryPlanner.java index a84300e65f..9440833503 100644 --- a/api/src/main/java/org/opensearch/sql/api/UnifiedQueryPlanner.java +++ b/api/src/main/java/org/opensearch/sql/api/UnifiedQueryPlanner.java @@ -27,6 +27,7 @@ import org.opensearch.sql.calcite.CalciteRelNodeVisitor; import org.opensearch.sql.common.antlr.SyntaxCheckException; import org.opensearch.sql.common.error.ErrorReport; +import org.opensearch.sql.exception.CalciteUnsupportedException; import org.opensearch.sql.exception.QueryEngineException; import org.opensearch.sql.exception.SemanticCheckException; @@ -73,6 +74,10 @@ public RelNode plan(String query) { } return plan; }); + } catch (CalciteUnsupportedException e) { + // Unsupported feature (e.g. table functions) is an invalid query, i.e. a client error. + // Must precede the QueryEngineException branch as it is a subclass. + throw new SemanticCheckException(e.getMessage(), e); } catch (SyntaxCheckException | QueryEngineException | UnsupportedOperationException diff --git a/api/src/test/java/org/opensearch/sql/api/UnifiedQueryPlannerTest.java b/api/src/test/java/org/opensearch/sql/api/UnifiedQueryPlannerTest.java index 296e9eb251..bb2d1e4a53 100644 --- a/api/src/test/java/org/opensearch/sql/api/UnifiedQueryPlannerTest.java +++ b/api/src/test/java/org/opensearch/sql/api/UnifiedQueryPlannerTest.java @@ -16,6 +16,7 @@ import org.junit.Test; import org.opensearch.sql.common.antlr.SyntaxCheckException; import org.opensearch.sql.common.error.ErrorReport; +import org.opensearch.sql.exception.CalciteUnsupportedException; import org.opensearch.sql.exception.SemanticCheckException; import org.opensearch.sql.executor.QueryType; @@ -147,6 +148,17 @@ public void invalidTableIsRethrownAsSemanticCheckException() { .assertCauseType(CalciteException.class); } + @Test + public void unsupportedFeatureIsRethrownAsSemanticCheckException() { + // A feature unsupported on the analytics engine (here a PPL command that raises + // CalciteUnsupportedException; SQL table functions like vectorSearch() take the same path) is + // an invalid query, normalized to a SemanticCheckException so callers classify it as a 4xx. + givenInvalidQuery("source = catalog.employees | kmeans") + .assertErrorType(SemanticCheckException.class) + .assertCauseType(CalciteUnsupportedException.class) + .assertErrorMessageContains("unsupported in Calcite"); + } + @Test public void assertionErrorIsWrappedAsSemanticCheckException() { // Remove when the underlying Calcite assertion is fixed.