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 4a609e7cc Differential Fuzzing (2/3): Check `PostgreSqlDialect` 
against PostgreSQL's own grammar (#2563)
4a609e7cc is described below

commit 4a609e7cc0d73754f8f03e0bc4011aaf0d288782
Author: Luca Cappelletti <[email protected]>
AuthorDate: Wed Sep 23 21:19:51 2026 +0000

    Differential Fuzzing (2/3): Check `PostgreSqlDialect` against PostgreSQL's 
own grammar (#2563)
---
 .clusterfuzzlite/Dockerfile                |  2 ++
 docs/fuzzing.md                            |  2 ++
 fuzz/Cargo.toml                            |  8 +++++++
 fuzz/fuzz_targets/fuzz_postgres_accepts.rs | 38 ++++++++++++++++++++++++++++++
 4 files changed, 50 insertions(+)

diff --git a/.clusterfuzzlite/Dockerfile b/.clusterfuzzlite/Dockerfile
index 579c99ad5..8eba3fdd6 100644
--- a/.clusterfuzzlite/Dockerfile
+++ b/.clusterfuzzlite/Dockerfile
@@ -16,6 +16,8 @@
 # under the License.
 
 FROM gcr.io/oss-fuzz-base/base-builder-rust
+# pg_query's build script runs bindgen, which needs libclang at build time
+RUN apt-get update && apt-get install -y --no-install-recommends libclang-dev 
&& rm -rf /var/lib/apt/lists/*
 COPY . $SRC/datafusion-sqlparser-rs
 WORKDIR $SRC/datafusion-sqlparser-rs
 COPY ./.clusterfuzzlite/build.sh $SRC/
diff --git a/docs/fuzzing.md b/docs/fuzzing.md
index 1714e06cd..7c56c0c77 100644
--- a/docs/fuzzing.md
+++ b/docs/fuzzing.md
@@ -33,6 +33,8 @@ rendered statement no longer parses.
 
 `fuzz_sqlite_accepts` compiles the input with a bundled SQLite, without 
running it, and fails when SQLite accepts SQL that `SQLiteDialect` rejects. 
Name resolution errors such as a missing table still count as accepted once 
SQLite has read the statement to its end.
 
+`fuzz_postgres_accepts` parses the input with PostgreSQL's own grammar through 
`pg_query` and fails when PostgreSQL accepts SQL that `PostgreSqlDialect` 
rejects.
+
 ClusterFuzzLite runs continuous fuzzing. Every pull request fuzzes for 10 
minutes in
 `code-change` mode, a daily batch job grows the shared corpus stored on the
 `clusterfuzzlite` branch, and a daily prune compacts it.
diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml
index 4242bf8ce..42c91742b 100644
--- a/fuzz/Cargo.toml
+++ b/fuzz/Cargo.toml
@@ -27,6 +27,7 @@ cargo-fuzz = true
 [dependencies]
 libfuzzer-sys = "0.4"
 libsqlite3-sys = { version = "0.38", features = ["bundled"] }
+pg_query = "6.2"
 sqlparser = { path = ".." }
 
 # Prevent this from interfering with workspaces
@@ -53,3 +54,10 @@ path = "fuzz_targets/fuzz_sqlite_accepts.rs"
 test = false
 doc = false
 bench = false
+
+[[bin]]
+name = "fuzz_postgres_accepts"
+path = "fuzz_targets/fuzz_postgres_accepts.rs"
+test = false
+doc = false
+bench = false
diff --git a/fuzz/fuzz_targets/fuzz_postgres_accepts.rs 
b/fuzz/fuzz_targets/fuzz_postgres_accepts.rs
new file mode 100644
index 000000000..e387d8ae6
--- /dev/null
+++ b/fuzz/fuzz_targets/fuzz_postgres_accepts.rs
@@ -0,0 +1,38 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#![no_main]
+
+use libfuzzer_sys::fuzz_target;
+use sqlparser::dialect::PostgreSqlDialect;
+use sqlparser::parser::{Parser, ParserError};
+
+fuzz_target!(|sql: &str| {
+    if sql.contains('\0') {
+        return;
+    }
+    let Ok(parsed) = pg_query::parse(sql) else {
+        return;
+    };
+    match Parser::parse_sql(&PostgreSqlDialect {}, sql) {
+        Ok(_) | Err(ParserError::RecursionLimitExceeded) => {}
+        Err(err) => panic!(
+            "PostgreSQL {} accepts SQL the PostgreSQL dialect rejects\n  sql: 
{sql:?}\n  error: {err}",
+            parsed.protobuf.version
+        ),
+    }
+});


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to