cargo-fuzz needs the nightly toolchain. Install it with rustup toolchain install nightly, then:
cargo install cargo-fuzz cd fuzz cargo +nightly fuzz run fuzz_parse_sql fuzz_seeds -- -max_total_time=600
There are two targets. fuzz_parse_sql parses the input with every dialect. fuzz_parse_roundtrip additionally re-parses the SQL rendered by Display and fails when a 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.
fuzz_duckdb_accepts parses the input with DuckDB's own parser and fails when DuckDB accepts a SELECT that DuckDbDialect rejects.
The three oracle targets compile their engine from source, so each builds only with its feature, sqlite, postgres or duckdb, as in cargo +nightly fuzz run --features sqlite fuzz_sqlite_accepts fuzz_seeds. cargo +nightly fuzz build --all-features builds every target.
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.
fuzz_seeds/ is a committed corpus of valid SQL that random mutation would never produce. The run command above uses it and build.sh packages it for ClusterFuzzLite.
Crashes land in artifacts/<target>/ and replay with cargo fuzz run <target> <crash-file>.