This is an automated email from the ASF dual-hosted git repository.

xuzifu666 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/main by this push:
     new d095b8cad6 [CALCITE-5973] Parsing DDL error message is inaccurate
d095b8cad6 is described below

commit d095b8cad68ceebe4d95f5c828e6389ee5cf9a36
Author: Yu Xu <[email protected]>
AuthorDate: Sat Oct 24 10:55:35 2026 +0800

    [CALCITE-5973] Parsing DDL error message is inaccurate
---
 core/src/main/codegen/templates/Parser.jj           |  7 ++++++-
 .../org/apache/calcite/runtime/CalciteResource.java |  6 ++++++
 .../calcite/runtime/CalciteResource.properties      |  1 +
 .../apache/calcite/test/ExceptionMessageTest.java   | 21 ++++++++++++++++++++-
 core/src/test/resources/sql/set-op.iq               |  2 +-
 .../apache/calcite/sql/parser/SqlParserTest.java    | 19 +++++++++++++++++++
 6 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/core/src/main/codegen/templates/Parser.jj 
b/core/src/main/codegen/templates/Parser.jj
index 726eaf45e9..6317b9c088 100644
--- a/core/src/main/codegen/templates/Parser.jj
+++ b/core/src/main/codegen/templates/Parser.jj
@@ -1301,7 +1301,12 @@ SqlNode SqlStmt() :
         stmt = SqlTruncate()
     |
 </#if>
-        stmt = OrderedQueryOrExpr(ExprContext.ACCEPT_QUERY)
+        stmt = OrderedQueryOrExpr(ExprContext.ACCEPT_NONCURSOR) {
+            if (!stmt.isA(SqlKind.QUERY)) {
+                throw SqlUtil.newContextException(stmt.getParserPosition(),
+                    RESOURCE.invalidStatement());
+            }
+        }
     |
         stmt = SqlExplain()
     |
diff --git a/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java 
b/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java
index 093fcb4e50..d7ceb5bbe2 100644
--- a/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java
+++ b/core/src/main/java/org/apache/calcite/runtime/CalciteResource.java
@@ -85,6 +85,12 @@ public interface CalciteResource {
   @BaseMessage("Non-query expression encountered in illegal context")
   ExInst<CalciteException> illegalNonQueryExpression();
 
+  /** Invalid statement, e.g. {@code "1 + 1"} is not a valid statement
+   * because a statement must be a query (SELECT, VALUES, TABLE)
+   * or a statement keyword (INSERT, UPDATE, DELETE, ...). */
+  @BaseMessage("Invalid SQL statement: query or other statement expected")
+  ExInst<CalciteException> invalidStatement();
+
   @BaseMessage("Query expression encountered in illegal context")
   ExInst<CalciteException> illegalQueryExpression();
 
diff --git 
a/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties 
b/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties
index 43c7e1db1b..4ef7f50d1d 100644
--- 
a/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties
+++ 
b/core/src/main/resources/org/apache/calcite/runtime/CalciteResource.properties
@@ -36,6 +36,7 @@ IllegalIntervalLiteral=Illegal INTERVAL literal {0}; at {1}
 IllegalMinusDate=Illegal expression. Was expecting "(DATETIME - DATETIME) 
INTERVALQUALIFIER"
 IllegalOverlaps=Illegal overlaps expression. Was expecting expression on the 
form "(DATETIME, EXPRESSION) OVERLAPS (DATETIME, EXPRESSION)"
 IllegalNonQueryExpression=Non-query expression encountered in illegal context
+InvalidStatement=Invalid SQL statement: query or other statement expected
 IllegalQueryExpression=Query expression encountered in illegal context
 IllegalCursorExpression=CURSOR expression encountered in illegal context
 IllegalOrderBy=ORDER BY unexpected
diff --git 
a/core/src/test/java/org/apache/calcite/test/ExceptionMessageTest.java 
b/core/src/test/java/org/apache/calcite/test/ExceptionMessageTest.java
index 825af84f4f..6fd264373b 100644
--- a/core/src/test/java/org/apache/calcite/test/ExceptionMessageTest.java
+++ b/core/src/test/java/org/apache/calcite/test/ExceptionMessageTest.java
@@ -161,7 +161,26 @@ private void runQuery(Function<RelBuilder, RelNode> relFn)
     } catch (SQLException e) {
       assertThat(e.getMessage(),
           equalTo("Error while executing SQL \"invalid sql\": parse failed: "
-              + "Non-query expression encountered in illegal context"));
+              + "Invalid SQL statement: query or other statement expected"));
+    }
+  }
+
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-5973";>[CALCITE-5973]
+   * Invalid statement yields misleading parse error</a>.
+   */
+  @Test void testSyntaxErrorOnInvalidStatement() {
+    try (Fixture f = new Fixture()) {
+      // Statement that cannot be parsed as any known statement or query;
+      // previously failed with the misleading message
+      // "Non-query expression encountered in illegal context"
+      f.runQuery("reate table t (a int, b varchar) with('key' = 'value')");
+      fail("Query should fail");
+    } catch (SQLException e) {
+      assertThat(e.getMessage(),
+          equalTo("Error while executing SQL \"reate table t (a int, b 
varchar)"
+              + " with('key' = 'value')\": parse failed: "
+              + "Invalid SQL statement: query or other statement expected"));
     }
   }
 
diff --git a/core/src/test/resources/sql/set-op.iq 
b/core/src/test/resources/sql/set-op.iq
index d1d998ea36..47bd82aefb 100644
--- a/core/src/test/resources/sql/set-op.iq
+++ b/core/src/test/resources/sql/set-op.iq
@@ -259,7 +259,7 @@ select * from emp where job = 'CLERK';
 (emp natural join dept)
 intersect
 select * from emp natural join dept where job = 'CLERK';
-Non-query expression encountered in illegal context
+parse failed: Encountered "natural" at line 1, column 6.
 !error
 
 # [CALCITE-6303] UNION with CTE(s) results in exception during query validation
diff --git 
a/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java 
b/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
index 3b3b9640bd..952a2c97cf 100644
--- a/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
+++ b/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
@@ -3507,6 +3507,25 @@ void checkPeriodPredicate(Checker checker) {
         .fails("Non-query expression encountered in illegal context");
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-5973";>[CALCITE-5973]
+   * Invalid statement yields misleading parse error</a>.
+   *
+   * <p>A statement that is neither a query (SELECT, VALUES, TABLE, ...) nor
+   * any other supported statement should fail with a meaningful message,
+   * not with "Non-query expression encountered in illegal context". */
+  @Test void testInvalidStatementFails() {
+    sql("^invalid^")
+        .fails("Invalid SQL statement: query or other statement expected");
+    sql("^1 + 1^")
+        .fails("Invalid SQL statement: query or other statement expected");
+    sql("^invalid^ sql")
+        .fails("Invalid SQL statement: query or other statement expected");
+    // Statement with a typo in the leading keyword
+    sql("^reate^ table t (a int, b varchar) with('key' = 'value')")
+        .fails("Invalid SQL statement: query or other statement expected");
+  }
+
   /**
    * In modern SQL, a query can occur almost everywhere that an expression
    * can. This test tests the few exceptions.

Reply via email to