You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by gi...@apache.org on 2026/10/16 14:19:15 UTC

(datafusion-sqlparser-rs) branch main updated: Assert exact errors in negative tests (4/4): deny clippy::assertions_on_result_states (#2631)

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

github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git


The following commit(s) were added to refs/heads/main by this push:
     new a80289f9 Assert exact errors in negative tests (4/4): deny clippy::assertions_on_result_states (#2631)
a80289f9 is described below

commit a80289f9f203f8546151b1a9084b0051bea4f8bb
Author: Luca Cappelletti <ca...@gmail.com>
AuthorDate: Fri Oct 16 14:17:10 2026 +0000

    Assert exact errors in negative tests (4/4): deny clippy::assertions_on_result_states (#2631)
---
 Cargo.toml                    |   3 +
 src/dialect/mod.rs            |   3 +-
 tests/no_std_recursion.rs     |  14 ++--
 tests/sqlparser_clickhouse.rs |  32 ++++++---
 tests/sqlparser_common.rs     | 162 +++++++++++++++++++++++++++++-------------
 tests/sqlparser_duckdb.rs     |  12 ++--
 tests/sqlparser_mysql.rs      |  49 +++++++++----
 tests/sqlparser_postgres.rs   | 152 ++++++++++++++++++---------------------
 tests/sqlparser_regression.rs |   3 +-
 tests/sqlparser_snowflake.rs  |  39 +++++-----
 10 files changed, 279 insertions(+), 190 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index a46bcbd3..a85de2e8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -39,6 +39,9 @@ path = "src/lib.rs"
 [lints.rust]
 unsafe_code = "forbid"
 
+[lints.clippy]
+assertions_on_result_states = "deny"
+
 [workspace]
 members = ["sqlparser_bench"]
 
diff --git a/src/dialect/mod.rs b/src/dialect/mod.rs
index bb6826f0..d3778994 100644
--- a/src/dialect/mod.rs
+++ b/src/dialect/mod.rs
@@ -2313,7 +2313,6 @@ mod tests {
         let statement = r#"SELECT 'Wayne\'s World'"#;
         let res1 = Parser::parse_sql(&MySqlDialect {}, statement);
         let res2 = Parser::parse_sql(&WrappedDialect(MySqlDialect {}), statement);
-        assert!(res1.is_ok());
-        assert_eq!(res1, res2);
+        assert_eq!(res1.unwrap(), res2.unwrap());
     }
 }
diff --git a/tests/no_std_recursion.rs b/tests/no_std_recursion.rs
index 86cf5c0d..e69e767d 100644
--- a/tests/no_std_recursion.rs
+++ b/tests/no_std_recursion.rs
@@ -52,10 +52,14 @@ fn deeply_nested_not_returns_error_without_default_features() {
 
     let result = Parser::parse_sql(&dialect, &sql);
 
-    // Note: Error is generic "expected end of statement" error rather than
-    // `RecursionLimitExceeded`. Either way, the important property is that deep
-    // nesting errors instead of overflowing the stack.
-    assert!(result.is_err());
+    // Deep nesting errors with a generic "expected end of statement" error
+    // rather than `RecursionLimitExceeded`, instead of overflowing the stack.
+    assert_eq!(
+        result,
+        Err(ParserError::ParserError(
+            "Expected: end of statement, found: NOT at Line: 1, Column: 211".to_string()
+        ))
+    );
 }
 
 #[test]
@@ -64,7 +68,7 @@ fn valid_nested_queries_parse_without_default_features() {
 
     let result = Parser::parse_sql(&dialect, "SELECT 1 + (2 + 3)");
 
-    assert!(result.is_ok());
+    result.unwrap();
 }
 
 #[test]
diff --git a/tests/sqlparser_clickhouse.rs b/tests/sqlparser_clickhouse.rs
index f86c0378..39e00bf3 100644
--- a/tests/sqlparser_clickhouse.rs
+++ b/tests/sqlparser_clickhouse.rs
@@ -1943,15 +1943,31 @@ fn parse_alter_table_modify_order_by() {
         _ => unreachable!(),
     }
 
-    for sql in [
-        "ALTER TABLE events MODIFY ORDER BY",
-        "ALTER TABLE events MODIFY ORDER BY (a",
-        "ALTER TABLE events MODIFY ORDER BY (,)",
-        "ALTER TABLE events MODIFY ORDER BY (a) b",
-        "CREATE TABLE events (a UInt8) ENGINE = MergeTree ORDER BY (a",
+    for (sql, err) in [
+        (
+            "ALTER TABLE events MODIFY ORDER BY",
+            "Expected: an expression, found: EOF",
+        ),
+        (
+            "ALTER TABLE events MODIFY ORDER BY (a",
+            "Expected: ), found: EOF",
+        ),
+        (
+            "ALTER TABLE events MODIFY ORDER BY (,)",
+            "Expected: an expression, found: ,",
+        ),
+        (
+            "ALTER TABLE events MODIFY ORDER BY (a) b",
+            "Expected: end of statement, found: b",
+        ),
+        (
+            "CREATE TABLE events (a UInt8) ENGINE = MergeTree ORDER BY (a",
+            "Expected: ), found: EOF",
+        ),
     ] {
-        assert!(
-            clickhouse_and_generic().parse_sql_statements(sql).is_err(),
+        assert_eq!(
+            clickhouse_and_generic().parse_sql_statements(sql),
+            Err(ParserError(err.to_string())),
             "{sql}"
         );
     }
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index bfe5bf67..e22c3802 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -11297,15 +11297,18 @@ fn parse_is_boolean() {
     verified_stmt("SELECT f FROM foo WHERE field IS UNKNOWN");
     verified_stmt("SELECT f FROM foo WHERE field IS NOT UNKNOWN");
 
-    for sql in [
-        "SELECT f from foo where field is 0",
-        "SELECT s, s IS XYZ NORMALIZED FROM foo",
-        "SELECT s, s IS NFKC FROM foo",
-        "SELECT s, s IS TRIM(' NFKC ') FROM foo",
+    for (sql, found) in [
+        ("SELECT f from foo where field is 0", "0"),
+        ("SELECT s, s IS XYZ NORMALIZED FROM foo", "XYZ"),
+        ("SELECT s, s IS NFKC FROM foo", "FROM"),
+        ("SELECT s, s IS TRIM(' NFKC ') FROM foo", "TRIM"),
     ] {
-        assert!(
-            parse_sql_statements(sql).is_err(),
-            "expected a parse failure for `{sql}`"
+        assert_eq!(
+            parse_sql_statements(sql),
+            Err(ParserError::ParserError(format!(
+                "Expected: [NOT] NULL | TRUE | FALSE | DISTINCT | [NOT] JSON [VALUE | SCALAR | ARRAY | OBJECT] [WITH | WITHOUT UNIQUE [KEYS]] | [form] NORMALIZED FROM after IS, found: {found}"
+            ))),
+            "{sql}"
         );
     }
 }
@@ -11352,26 +11355,64 @@ fn parse_is_json_predicate() {
 fn parse_is_json_predicate_invalid() {
     let dialects = all_dialects();
 
-    let invalid = [
-        "SELECT * FROM t WHERE a IS JSON WITH FROM",
-        "SELECT * FROM t WHERE a IS JSON WITH KEYS",
-        "SELECT * FROM t WHERE a IS JSON WITHOUT FROM",
-        "SELECT * FROM t WHERE a IS JSON WITHOUT KEYS",
-        "SELECT * FROM t WHERE a IS NOT JSON WITH FROM",
-        "SELECT * FROM t WHERE a IS JSON VALUE ARRAY",
-        "SELECT * FROM t WHERE a IS JSON OBJECT VALUE",
-        "SELECT * FROM t WHERE a IS JSON WITH UNIQUE EXTRA",
-        "SELECT * FROM t WHERE a IS JSON WITH UNIQUE KEYS EXTRA",
-        "SELECT * FROM t WHERE a IS JSON WITHOUT UNIQUE EXTRA",
-        "SELECT * FROM t WHERE a IS JSON WITHOUT UNIQUE KEYS EXTRA",
-        "SELECT * FROM t WHERE a IS JSON WITH UNIQUE KEYS WITH UNIQUE KEYS",
-        "SELECT * FROM t WHERE a IS JSON WITHOUT UNIQUE KEYS WITHOUT UNIQUE KEYS",
-    ];
-
-    for sql in invalid {
-        assert!(
-            dialects.parse_sql_statements(sql).is_err(),
-            "expected a parse failure for `{sql}`"
+    for (sql, err) in [
+        (
+            "SELECT * FROM t WHERE a IS JSON WITH FROM",
+            "Expected: UNIQUE, found: FROM",
+        ),
+        (
+            "SELECT * FROM t WHERE a IS JSON WITH KEYS",
+            "Expected: UNIQUE, found: KEYS",
+        ),
+        (
+            "SELECT * FROM t WHERE a IS JSON WITHOUT FROM",
+            "Expected: UNIQUE, found: FROM",
+        ),
+        (
+            "SELECT * FROM t WHERE a IS JSON WITHOUT KEYS",
+            "Expected: UNIQUE, found: KEYS",
+        ),
+        (
+            "SELECT * FROM t WHERE a IS NOT JSON WITH FROM",
+            "Expected: UNIQUE, found: FROM",
+        ),
+        (
+            "SELECT * FROM t WHERE a IS JSON VALUE ARRAY",
+            "Expected: end of statement, found: ARRAY",
+        ),
+        (
+            "SELECT * FROM t WHERE a IS JSON OBJECT VALUE",
+            "Expected: end of statement, found: VALUE",
+        ),
+        (
+            "SELECT * FROM t WHERE a IS JSON WITH UNIQUE EXTRA",
+            "Expected: end of statement, found: EXTRA",
+        ),
+        (
+            "SELECT * FROM t WHERE a IS JSON WITH UNIQUE KEYS EXTRA",
+            "Expected: end of statement, found: EXTRA",
+        ),
+        (
+            "SELECT * FROM t WHERE a IS JSON WITHOUT UNIQUE EXTRA",
+            "Expected: end of statement, found: EXTRA",
+        ),
+        (
+            "SELECT * FROM t WHERE a IS JSON WITHOUT UNIQUE KEYS EXTRA",
+            "Expected: end of statement, found: EXTRA",
+        ),
+        (
+            "SELECT * FROM t WHERE a IS JSON WITH UNIQUE KEYS WITH UNIQUE KEYS",
+            "Expected: end of statement, found: WITH",
+        ),
+        (
+            "SELECT * FROM t WHERE a IS JSON WITHOUT UNIQUE KEYS WITHOUT UNIQUE KEYS",
+            "Expected: end of statement, found: WITHOUT",
+        ),
+    ] {
+        assert_eq!(
+            dialects.parse_sql_statements(sql),
+            Err(ParserError::ParserError(err.to_string())),
+            "{sql}"
         );
     }
 }
@@ -14008,15 +14049,21 @@ fn test_match_recognize_patterns() {
         ]),
     );
 
-    for pattern in ["S1**", "S1+++", "S1???", "S1{2,4}+"] {
+    for (pattern, found) in [
+        ("S1**", "*"),
+        ("S1+++", "+"),
+        ("S1???", "?"),
+        ("S1{2,4}+", "+"),
+    ] {
         let sql = format!(
             "SELECT * FROM my_table MATCH_RECOGNIZE(PATTERN ({pattern}) DEFINE DUMMY AS 1 = 1)"
         );
-        assert!(
-            all_dialects_where(|d| d.supports_match_recognize())
-                .parse_sql_statements(&sql)
-                .is_err(),
-            "stacked quantifier should fail: {pattern}"
+        assert_eq!(
+            all_dialects_where(|d| d.supports_match_recognize()).parse_sql_statements(&sql),
+            Err(ParserError::ParserError(format!(
+                "Expected: identifier, found: {found}"
+            ))),
+            "{pattern}"
         );
     }
 
@@ -19132,14 +19179,21 @@ fn test_parse_semantic_view_table_factor() {
         }
     }
 
-    let invalid_sqls = [
-        "SELECT * FROM SEMANTIC_VIEW(model DIMENSIONS dim1 INVALID inv1)",
-        "SELECT * FROM SEMANTIC_VIEW(model DIMENSIONS dim1 DIMENSIONS dim2)",
-    ];
-
-    for sql in invalid_sqls {
-        let result = dialects.parse_sql_statements(sql);
-        assert!(result.is_err(), "Expected error for invalid SQL: {sql}");
+    for (sql, err) in [
+        (
+            "SELECT * FROM SEMANTIC_VIEW(model DIMENSIONS dim1 INVALID inv1)",
+            "Expected one of DIMENSIONS, METRICS, FACTS or WHERE, got INVALID",
+        ),
+        (
+            "SELECT * FROM SEMANTIC_VIEW(model DIMENSIONS dim1 DIMENSIONS dim2)",
+            "DIMENSIONS clause can only be specified once",
+        ),
+    ] {
+        assert_eq!(
+            dialects.parse_sql_statements(sql),
+            Err(ParserError::ParserError(err.to_string())),
+            "{sql}"
+        );
     }
 
     let ast_sql = r#"SELECT * FROM SEMANTIC_VIEW(
@@ -19630,10 +19684,12 @@ fn test_parse_set_session_authorization() {
 #[test]
 fn test_set_authorization_without_scope_errors() {
     // This should return a parser error, not panic.
-    let res = parse_sql_statements("SET AUTHORIZATION TIME TIME");
-    assert!(
-        res.is_err(),
-        "SET AUTHORIZATION without a scope modifier (e.g. SESSION) should error"
+    assert_eq!(
+        parse_sql_statements("SET AUTHORIZATION TIME TIME"),
+        Err(ParserError::ParserError(
+            "Expected: SESSION, LOCAL, or other scope modifier before AUTHORIZATION, found: AUTHORIZATION"
+                .to_string()
+        ))
     );
 }
 
@@ -20270,11 +20326,17 @@ fn parse_alter_table_column_position() {
     );
 
     let dialects = all_dialects_where(|d| !d.supports_alter_column_position());
-    for sql in [
-        "ALTER TABLE tab ADD COLUMN c INT FIRST",
-        "ALTER TABLE tab ADD COLUMN c INT AFTER b",
+    for (sql, found) in [
+        ("ALTER TABLE tab ADD COLUMN c INT FIRST", "FIRST"),
+        ("ALTER TABLE tab ADD COLUMN c INT AFTER b", "AFTER"),
     ] {
-        assert!(dialects.parse_sql_statements(sql).is_err(), "{sql}");
+        assert_eq!(
+            dialects.parse_sql_statements(sql),
+            Err(ParserError::ParserError(format!(
+                "Expected: end of statement, found: {found}"
+            ))),
+            "{sql}"
+        );
     }
 }
 
diff --git a/tests/sqlparser_duckdb.rs b/tests/sqlparser_duckdb.rs
index ebf620f4..158b8637 100644
--- a/tests/sqlparser_duckdb.rs
+++ b/tests/sqlparser_duckdb.rs
@@ -933,12 +933,10 @@ fn test_duckdb_nested_block_comments() {
         "SELECT a FROM t",
     );
 
-    let err = duckdb()
-        .parse_sql_statements("SELECT a /* outer /* inner */ FROM t")
-        .unwrap_err();
-    assert!(
-        err.to_string()
-            .contains("Unexpected EOF while in a multi-line comment"),
-        "{err}"
+    assert_eq!(
+        duckdb().parse_sql_statements("SELECT a /* outer /* inner */ FROM t"),
+        Err(ParserError::TokenizerError(
+            "Unexpected EOF while in a multi-line comment at Line: 1, Column: 37".to_string()
+        ))
     );
 }
diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs
index ca80f726..13c27d66 100644
--- a/tests/sqlparser_mysql.rs
+++ b/tests/sqlparser_mysql.rs
@@ -1946,13 +1946,18 @@ fn parse_zerofill() {
         mysql_and_generic().verified_stmt(&format!("CREATE TABLE t (a {data_type} ZEROFILL)"));
     }
     mysql_and_generic().verified_stmt("CREATE TABLE t (a INT(10) UNSIGNED ZEROFILL)");
-    assert!(mysql_and_generic()
-        .parse_sql_statements("CREATE TABLE t (a VARCHAR(10) ZEROFILL)")
-        .is_err());
-    assert!(
+    assert_eq!(
+        mysql_and_generic().parse_sql_statements("CREATE TABLE t (a VARCHAR(10) ZEROFILL)"),
+        Err(ParserError::ParserError(
+            "Expected: ',' or ')' after column definition, found: ZEROFILL".to_string()
+        ))
+    );
+    assert_eq!(
         all_dialects_except(|d| d.supports_data_type_zerofill_suffix())
-            .parse_sql_statements("CREATE TABLE t (a INT ZEROFILL)")
-            .is_err()
+            .parse_sql_statements("CREATE TABLE t (a INT ZEROFILL)"),
+        Err(ParserError::ParserError(
+            "Expected: ',' or ')' after column definition, found: ZEROFILL".to_string()
+        ))
     );
 }
 
@@ -5162,15 +5167,31 @@ fn parse_alter_table_column_position() {
     mysql_and_generic().verified_stmt("ALTER TABLE tab ADD COLUMN a INT FIRST, CHANGE COLUMN b c INT AFTER a, MODIFY COLUMN d INT AFTER c");
 
     // FIRST and AFTER are mutually exclusive, and AFTER needs a target.
-    for sql in [
-        "ALTER TABLE tab ADD COLUMN c INT FIRST AFTER b",
-        "ALTER TABLE tab ADD COLUMN c INT AFTER b FIRST",
-        "ALTER TABLE tab ADD COLUMN c INT AFTER",
-        "ALTER TABLE tab CHANGE COLUMN a b INT AFTER",
-        "ALTER TABLE tab MODIFY COLUMN c INT AFTER",
+    for (sql, err) in [
+        (
+            "ALTER TABLE tab ADD COLUMN c INT FIRST AFTER b",
+            "Expected: end of statement, found: AFTER",
+        ),
+        (
+            "ALTER TABLE tab ADD COLUMN c INT AFTER b FIRST",
+            "Expected: end of statement, found: FIRST",
+        ),
+        (
+            "ALTER TABLE tab ADD COLUMN c INT AFTER",
+            "Expected: identifier, found: EOF",
+        ),
+        (
+            "ALTER TABLE tab CHANGE COLUMN a b INT AFTER",
+            "Expected: identifier, found: EOF",
+        ),
+        (
+            "ALTER TABLE tab MODIFY COLUMN c INT AFTER",
+            "Expected: identifier, found: EOF",
+        ),
     ] {
-        assert!(
-            mysql_and_generic().parse_sql_statements(sql).is_err(),
+        assert_eq!(
+            mysql_and_generic().parse_sql_statements(sql),
+            Err(ParserError::ParserError(err.to_string())),
             "{sql}"
         );
     }
diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs
index 123285b6..cb50fbf9 100644
--- a/tests/sqlparser_postgres.rs
+++ b/tests/sqlparser_postgres.rs
@@ -669,15 +669,13 @@ fn parse_exclude_constraint() {
 
     // Dialects that do not opt in via `supports_exclude_constraint` must
     // refuse to parse `EXCLUDE` constraints.
-    let unsupported = all_dialects_where(|d| !d.supports_exclude_constraint());
-    let sql = "CREATE TABLE t (col INT, EXCLUDE USING gist (col WITH =))";
-    for dialect in unsupported.dialects {
-        let parser = TestedDialects::new(vec![dialect]);
-        assert!(
-            parser.parse_sql_statements(sql).is_err(),
-            "dialect unexpectedly accepted EXCLUDE: {sql}"
-        );
-    }
+    assert_eq!(
+        all_dialects_where(|d| !d.supports_exclude_constraint())
+            .parse_sql_statements("CREATE TABLE t (col INT, EXCLUDE USING gist (col WITH =))"),
+        Err(ParserError::ParserError(
+            "Expected: ',' or ')' after column definition, found: gist".to_string()
+        ))
+    );
 }
 
 #[test]
@@ -4539,9 +4537,12 @@ fn parse_create_role() {
 
     for negatable_kw in negatables.iter() {
         let sql = format!("CREATE ROLE abc {negatable_kw} NO{negatable_kw}");
-        if pg().parse_sql_statements(&sql).is_ok() {
-            panic!("Should not be able to parse CREATE ROLE containing both negated and non-negated versions of the same keyword: {negatable_kw}")
-        }
+        assert_eq!(
+            pg().parse_sql_statements(&sql),
+            Err(ParserError::ParserError(format!(
+                "Found multiple {negatable_kw} or NO{negatable_kw}"
+            )))
+        );
     }
 }
 
@@ -9453,68 +9454,42 @@ CONSTRAINT check_date CHECK (order_date >= '2023-01-01')\
 
 #[test]
 fn parse_create_table_partition_of_errors() {
-    let sql = "CREATE TABLE p PARTITION OF parent";
-    let result = pg_and_generic().parse_sql_statements(sql);
-    assert!(result.is_err());
-    let err = result.unwrap_err().to_string();
-    assert!(
-        err.contains("FOR VALUES or DEFAULT"),
-        "Expected error about FOR VALUES, got: {err}"
-    );
-
-    let sql = "CREATE TABLE p PARTITION OF parent WITH (fillfactor = 70)";
-    let result = pg_and_generic().parse_sql_statements(sql);
-    assert!(result.is_err());
-    let err = result.unwrap_err().to_string();
-    assert!(
-        err.contains("FOR VALUES or DEFAULT"),
-        "Expected error about FOR VALUES, got: {err}"
-    );
-
-    let sql = "CREATE TABLE p PARTITION OF parent FOR VALUES RANGE (1, 10)";
-    let result = pg_and_generic().parse_sql_statements(sql);
-    assert!(result.is_err());
-    let err = result.unwrap_err().to_string();
-    assert!(
-        err.contains("IN, FROM, or WITH"),
-        "Expected error about invalid keyword after FOR VALUES, got: {err}"
-    );
-
-    let sql = "CREATE TABLE p PARTITION OF parent FOR VALUES FROM (1)";
-    let result = pg_and_generic().parse_sql_statements(sql);
-    assert!(result.is_err());
-    let err = result.unwrap_err().to_string();
-    assert!(
-        err.contains("TO"),
-        "Expected error about missing TO clause, got: {err}"
-    );
-
-    let sql = "CREATE TABLE p PARTITION OF parent FOR VALUES IN ()";
-    let result = pg_and_generic().parse_sql_statements(sql);
-    assert!(result.is_err());
-    let err = result.unwrap_err().to_string();
-    assert!(
-        err.contains("at least one value"),
-        "Expected error about empty value list in IN clause, got: {err}"
-    );
-
-    let sql = "CREATE TABLE p PARTITION OF parent FOR VALUES FROM () TO (10)";
-    let result = pg_and_generic().parse_sql_statements(sql);
-    assert!(result.is_err());
-    let err = result.unwrap_err().to_string();
-    assert!(
-        err.contains("at least one value"),
-        "Expected error about empty FROM list, got: {err}"
-    );
-
-    let sql = "CREATE TABLE p PARTITION OF parent FOR VALUES FROM (1) TO ()";
-    let result = pg_and_generic().parse_sql_statements(sql);
-    assert!(result.is_err());
-    let err = result.unwrap_err().to_string();
-    assert!(
-        err.contains("at least one value"),
-        "Expected error about empty TO list, got: {err}"
-    );
+    for (sql, err) in [
+        (
+            "CREATE TABLE p PARTITION OF parent",
+            "Expected: FOR VALUES or DEFAULT after PARTITION OF, found: EOF",
+        ),
+        (
+            "CREATE TABLE p PARTITION OF parent WITH (fillfactor = 70)",
+            "Expected: FOR VALUES or DEFAULT after PARTITION OF, found: WITH",
+        ),
+        (
+            "CREATE TABLE p PARTITION OF parent FOR VALUES RANGE (1, 10)",
+            "Expected: IN, FROM, or WITH after FOR VALUES, found: RANGE",
+        ),
+        (
+            "CREATE TABLE p PARTITION OF parent FOR VALUES FROM (1)",
+            "Expected: TO, found: EOF",
+        ),
+        (
+            "CREATE TABLE p PARTITION OF parent FOR VALUES IN ()",
+            "Expected: at least one value, found: )",
+        ),
+        (
+            "CREATE TABLE p PARTITION OF parent FOR VALUES FROM () TO (10)",
+            "Expected: at least one value, found: )",
+        ),
+        (
+            "CREATE TABLE p PARTITION OF parent FOR VALUES FROM (1) TO ()",
+            "Expected: at least one value, found: )",
+        ),
+    ] {
+        assert_eq!(
+            pg_and_generic().parse_sql_statements(sql),
+            Err(ParserError::ParserError(err.to_string())),
+            "{sql}"
+        );
+    }
 }
 
 #[test]
@@ -10052,15 +10027,28 @@ fn parse_insert_overriding() {
 
     // `OVERRIDING` takes `SYSTEM` or `USER`, then `VALUE`, and is followed by a query: PostgreSQL's
     // grammar does not allow it before `DEFAULT VALUES`.
-    for sql in [
-        "INSERT INTO t (id) OVERRIDING VALUE VALUES (1)",
-        "INSERT INTO t (id) OVERRIDING SYSTEM VALUES (1)",
-        "INSERT INTO t (id) OVERRIDING DEFAULT VALUE VALUES (1)",
-        "INSERT INTO t OVERRIDING SYSTEM VALUE DEFAULT VALUES",
+    for (sql, err) in [
+        (
+            "INSERT INTO t (id) OVERRIDING VALUE VALUES (1)",
+            "Expected: SYSTEM or USER, found: VALUE",
+        ),
+        (
+            "INSERT INTO t (id) OVERRIDING SYSTEM VALUES (1)",
+            "Expected: VALUE, found: VALUES",
+        ),
+        (
+            "INSERT INTO t (id) OVERRIDING DEFAULT VALUE VALUES (1)",
+            "Expected: SYSTEM or USER, found: DEFAULT",
+        ),
+        (
+            "INSERT INTO t OVERRIDING SYSTEM VALUE DEFAULT VALUES",
+            "Expected: SELECT, VALUES, or a subquery in the query body, found: DEFAULT",
+        ),
     ] {
-        assert!(
-            pg_and_generic().parse_sql_statements(sql).is_err(),
-            "{sql} should not parse"
+        assert_eq!(
+            pg_and_generic().parse_sql_statements(sql),
+            Err(ParserError::ParserError(err.to_string())),
+            "{sql}"
         );
     }
 }
diff --git a/tests/sqlparser_regression.rs b/tests/sqlparser_regression.rs
index 55e03c45..fea745e3 100644
--- a/tests/sqlparser_regression.rs
+++ b/tests/sqlparser_regression.rs
@@ -30,8 +30,7 @@ macro_rules! tpch_tests {
         #[test]
         fn $name() {
             let dialect = GenericDialect {};
-            let res = Parser::parse_sql(&dialect, QUERIES[$value -1]);
-                assert!(res.is_ok());
+            Parser::parse_sql(&dialect, QUERIES[$value -1]).unwrap();
         }
     )*
     }
diff --git a/tests/sqlparser_snowflake.rs b/tests/sqlparser_snowflake.rs
index ec73748a..6c8c73c6 100644
--- a/tests/sqlparser_snowflake.rs
+++ b/tests/sqlparser_snowflake.rs
@@ -4831,18 +4831,19 @@ fn test_snowflake_identifier_function() {
 
     // Cannot have more than one IDENTIFIER part in an object name
     assert_eq!(
-        snowflake()
-            .parse_sql_statements(
-                "CREATE TABLE IDENTIFIER('db1').IDENTIFIER('sc1').IDENTIFIER('tbl') (id INT)"
-            )
-            .is_err(),
-        true
+        snowflake().parse_sql_statements(
+            "CREATE TABLE IDENTIFIER('db1').IDENTIFIER('sc1').IDENTIFIER('tbl') (id INT)"
+        ),
+        Err(ParserError::ParserError(
+            "Expected: column name or constraint definition, found: 'sc1'".to_string()
+        ))
     );
     assert_eq!(
         snowflake()
-            .parse_sql_statements("CREATE TABLE IDENTIFIER('db1')..IDENTIFIER('tbl') (id INT)")
-            .is_err(),
-        true
+            .parse_sql_statements("CREATE TABLE IDENTIFIER('db1')..IDENTIFIER('tbl') (id INT)"),
+        Err(ParserError::ParserError(
+            "Expected: column name or constraint definition, found: 'tbl'".to_string()
+        ))
     );
 }
 
@@ -4884,17 +4885,15 @@ fn test_create_database() {
         WITH CONTACT (owner = admin, dpo = compliance)",
     );
 
-    let err = snowflake()
-        .parse_sql_statements("CREATE DATABASE")
-        .unwrap_err()
-        .to_string();
-    assert!(err.contains("Expected"), "Unexpected error: {err}");
-
-    let err = snowflake()
-        .parse_sql_statements("CREATE DATABASE my_db CLONE")
-        .unwrap_err()
-        .to_string();
-    assert!(err.contains("Expected"), "Unexpected error: {err}");
+    for sql in ["CREATE DATABASE", "CREATE DATABASE my_db CLONE"] {
+        assert_eq!(
+            snowflake().parse_sql_statements(sql),
+            Err(ParserError::ParserError(
+                "Expected: identifier, found: EOF".to_string()
+            )),
+            "{sql}"
+        );
+    }
 }
 
 #[test]


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org