Multi-dialect SQL parser and translator in Rust.
Parses SQL from MySQL, MariaDB, PostgreSQL, MSSQL (T-SQL), and SQLite into a JSON AST, emits SQL back from JSON, and translates between dialects.
Status: early development — see
CHANGELOG.mdfor what's shipped andOUT-OF-SCOPE.mdfor what isn't.
# Homebrew (macOS / Linux) — via the codedeviate tap
brew install codedeviate/cli/sqlt
# crates.io
cargo install sqlt
# From a clone of this repo
cargo install --path .# Parse SQL → JSON AST
echo "SELECT 1" | sqlt parse --from mysql --pretty
# Emit JSON AST → SQL
sqlt parse --from postgres schema.sql | sqlt emit --to mysql
# Translate SQL between dialects
sqlt translate --from mariadb --to postgres input.sql
# Lint SQL for common pitfalls and improvement suggestions
sqlt lint --from mariadb schema.sql
sqlt lint --from mariadb --to postgres schema.sql # adds translation pre-flight checks
sqlt lint --from mariadb --format json schema.sql # JSON output
sqlt lint --from mariadb --format sarif schema.sql # SARIF for GitHub code scanning
sqlt lint --explain SQLT0300 # rule documentationReads from a file path or stdin (use - or omit the path).
After installing via Homebrew, man sqlt opens the full system man page (sections: SYNOPSIS, COMMANDS, DIALECTS, ENCODINGS, LINT RULE CATEGORIES, TRANSLATION WARNINGS, EXAMPLES, EXIT STATUS, FILES, ENVIRONMENT). The source for the page lives at man/sqlt.1.
mysql, mariadb, postgres (alias postgresql), mssql (alias tsql), sqlite, generic.
MariaDB is a first-class target — features that diverge from MySQL (RETURNING on DML, CREATE SEQUENCE, system versioning, FOR SYSTEM_TIME, Oracle-compat packages) are recognized rather than silently aliased.
Pass --encoding/-e to read or write SQL in a non-UTF-8 code page. Useful when one of your systems still emits ISO-8859-1 / Latin-1.
sqlt parse --from mysql -e latin1 export.sql # decode latin1, emit UTF-8 JSON
sqlt translate --from mysql --to mariadb -e latin1 in.sql > out.sql # latin1 in and out
sqlt emit --to mysql -e windows-1252 tree.json # JSON (UTF-8) -> windows-1252 SQLSupported encodings: utf-8 (default), iso-8859-1 / latin1, windows-1252 / cp1252. Decoding is strict — invalid bytes for the declared encoding are rejected with exit 1 rather than silently replaced.
When a construct has no faithful equivalent in the target dialect (e.g. translating RETURNING to MySQL), sqlt translate emits the closest equivalent and prints a warning to stderr. Pass --strict to make any warning a non-zero exit.
sqlt lint runs ~38 rules across seven categories: dialect cross-contamination, translation pre-flight (when --to is set), join hygiene, subquery improvements, performance pitfalls, correctness pitfalls, style/readability, and DDL hygiene. Every rule has a stable id (SQLT0500), a slug (select-star), and inline documentation (sqlt lint --explain SQLT0500).
Common flags:
--from <dialect> required; the source SQL dialect
--to <dialect> optional; enables translation pre-flight rules
--format text|pretty|json|sarif output format (default text)
--rule <id>... enable a specific rule (repeatable)
--no-rule <id>... disable a specific rule (repeatable)
--severity error|warning|info filter the output (rules still run)
--exit-on error|warning|info controls exit code 1 (default error)
--explain <id> print rule documentation and exit 0
-e, --encoding same encoding handling as parse/translate
Exit codes match the rest of the CLI: 0 clean, 1 lint findings at or above --exit-on (or a parse error), 2 usage error, 3 reserved.
cargo build
cargo test
cargo clippy -- -D warnings
cargo fmt --checkSee CLAUDE.md for project conventions (semver, conventional commits, changelog, module map).
MIT — see LICENSE.