sqlformat
Format SQL strings into readable, consistently styled output. sqlformat
is a pure-Rust library designed to pretty-print SQL from a variety of mainstream dialects, ideal for logging, debugging, tests, or developer tools.
This crate is a Rust port of sql-formatter-plus. There is currently no binary; the crate is intended to be used as a library.
Key features
- Broad SQL support: Common constructs from PostgreSQL, MySQL/MariaDB, SQLite, SQL Server, and Oracle (DDL, DML, CTEs, CASE, JOINs, window functions, operators, type casts, etc.).
- Configurable style: Indentation (spaces or tabs), upper/lower/preserve keyword case, control lines between statements.
- Inline controls: Keep short blocks or argument lists inline when they fit; split when they don’t.
- Parameter interpolation: Supports
?
,?1
,$1
,$name
,:name
,@name
, and bracketed variants viaQueryParams
. - Comment-aware: Respects line/block comments; supports in-query toggles to temporarily disable formatting.
- Safe Rust:
#![forbid(unsafe_code)]
.
Quick start
use ;
Output:
SELECT
id,
name
FROM
users
WHERE
created_at > NOW();
Installation
Add via Cargo:
Or manually in Cargo.toml
:
[]
= "*"
Minimum Supported Rust Version (MSRV): 1.84
.
Usage examples
Basic formatting
use ;
let sql = "SELECT count(*), col FROM t WHERE a = 1 AND b = 2;";
let out = format;
Indentation
use ;
let options = FormatOptions ;
let out = format;
let options = FormatOptions ;
let out = format;
Keyword case conversion
use ;
// Uppercase reserved keywords
let options = FormatOptions ;
let out = format;
// Lowercase reserved keywords
let options = FormatOptions ;
let out = format;
// Preserve case with exceptions
let options = FormatOptions ;
let out = format;
Inline/compact formatting
Control how aggressively short blocks and argument lists are kept on one line.
use ;
let options = FormatOptions ;
let out = format;
JOIN layout
Treat any JOIN as a top-level keyword (affects line breaks):
use ;
let options = FormatOptions ;
let out = format;
Parameter interpolation
sqlformat
can substitute placeholders using QueryParams
:
use ;
// Numbered / positional (e.g., ?, ?1, $1)
let sql = "SELECT ?1, ?, $2;";
let params = Indexed;
let out = format;
// Named (e.g., $name, :name, @name, :\"weird name\")
let sql = "SELECT $hash, :name, @`var name`;";
let params = Named;
let out = format;
Controlling blank lines between statements
use ;
let options = FormatOptions ;
let out = format;
Temporarily disabling the formatter
You can turn formatting off/on using SQL comments. This is helpful when you want to preserve a very specific layout.
-- fmt: off
SELECT * FROM t WHERE a=1 AND b=2; -- preserved as-is
-- fmt: on
/* fmt: off */ SELECT 1 + 2; /* fmt: on */
Configuration reference
The formatter is configured through FormatOptions
. See the full API on the docs site for list of options.
API reference
- Crate docs:
docs.rs/sqlformat
- Primary entry point:
format(query: &str, params: &QueryParams, options: &FormatOptions) -> String
Contributing
Contributions are welcome!
- Run tests:
cargo test
- Run benchmarks (optional):
cargo bench
Please open issues and pull requests with clear descriptions and examples. Bug reports that include an input SQL snippet, your FormatOptions
, and the actual vs. expected output are especially helpful.
License
Dual-licensed under either of:
- MIT License (
LICENSE-MIT
) - Apache License, Version 2.0 (
LICENSE-APACHE
)
Acknowledgements
Based on the excellent work in sql-formatter-plus
.