- Notifications
You must be signed in to change notification settings - Fork32
SQL Formatter written in Rust
License
Apache-2.0, MIT licenses found
Licenses found
shssoichiro/sqlformat-rs
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
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 ofsql-formatter-plus. There is currently no binary; the crate is intended to be used as a library.
- 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)].
use sqlformat::{format,FormatOptions,Indent,QueryParams};fnmain(){let sql ="SELECT id, name FROM users WHERE created_at > NOW();";let options =FormatOptions::default();let formatted =format(sql,&QueryParams::None,&options);println!("{}", formatted);}
Output:
SELECT id, nameFROM usersWHERE created_at > NOW();Add via Cargo:
cargo add sqlformat
Or manually inCargo.toml:
[dependencies]sqlformat ="*"
Minimum Supported Rust Version (MSRV):1.84.
use sqlformat::{format,FormatOptions,QueryParams};let sql ="SELECT count(*), col FROM t WHERE a = 1 AND b = 2;";let out =format(sql,&QueryParams::None,&FormatOptions::default());
use sqlformat::{format,FormatOptions,Indent,QueryParams};let options =FormatOptions{indent:Indent::Spaces(4), ..Default::default()};let out =format("SELECT a, b FROM t;",&QueryParams::None,&options);let options =FormatOptions{indent:Indent::Tabs, ..Default::default()};let out =format("SELECT a, b FROM t;",&QueryParams::None,&options);
use sqlformat::{format,FormatOptions,QueryParams};// Uppercase reserved keywordslet options =FormatOptions{uppercase:Some(true), ..Default::default()};let out =format("select distinct * from foo where bar = 1",&QueryParams::None,&options);// Lowercase reserved keywordslet options =FormatOptions{uppercase:Some(false), ..Default::default()};let out =format("SELECT DISTINCT * FROM FOO WHERE BAR = 1",&QueryParams::None,&options);// Preserve case with exceptionslet options =FormatOptions{uppercase:Some(true),ignore_case_convert:Some(vec!["from","where"]), ..Default::default()};let out =format("select * from foo where bar = 1",&QueryParams::None,&options);
Control how aggressively short blocks and argument lists are kept on one line.
use sqlformat::{format,FormatOptions,QueryParams};let options =FormatOptions{inline:false,// when true, forces single-line outputmax_inline_block:50,// characters allowed to keep a parenthesized block inlinemax_inline_arguments:Some(40),max_inline_top_level:Some(40), ..Default::default()};let out =format("SELECT a, b, c, d, e, f, g, h FROM t;",&QueryParams::None,&options);
Treat any JOIN as a top-level keyword (affects line breaks):
use sqlformat::{format,FormatOptions,QueryParams};let options =FormatOptions{joins_as_top_level:true, ..Default::default()};let out =format("SELECT * FROM a INNER JOIN b ON a.id = b.a_id",&QueryParams::None,&options);
sqlformat can substitute placeholders usingQueryParams:
use sqlformat::{format,FormatOptions,QueryParams};// Numbered / positional (e.g., ?, ?1, $1)let sql ="SELECT ?1, ?, $2;";let params =QueryParams::Indexed(vec!["first".to_string(),"second".to_string(),"third".to_string()]);let out =format(sql,¶ms,&FormatOptions::default());// Named (e.g., $name, :name, @name, :\"weird name\")let sql ="SELECT $hash, :name, @`var name`;";let params =QueryParams::Named(vec![("hash".to_string(),"hash value".to_string()),("name".to_string(),"Alice".to_string()),("var name".to_string(),"Bob".to_string()),]);let out =format(sql,¶ms,&FormatOptions::default());
use sqlformat::{format,FormatOptions,QueryParams};let options =FormatOptions{lines_between_queries:2, ..Default::default()};let out =format("SELECT 1; SELECT 2;",&QueryParams::None,&options);
You can turn formatting off/on using SQL comments. This is helpful when you want to preserve a very specific layout.
-- fmt: offSELECT*FROM tWHERE a=1AND b=2;-- preserved as-is-- fmt: on/* fmt: off*/SELECT1+2;/* fmt: on*/
The formatter is configured throughFormatOptions. See the full API on the docs site for list of options.
- Crate docs:
docs.rs/sqlformat - Primary entry point:
format(query: &str, params: &QueryParams, options: &FormatOptions) -> String
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, yourFormatOptions, and the actual vs. expected output are especially helpful.
Dual-licensed under either of:
- MIT License (
LICENSE-MIT) - Apache License, Version 2.0 (
LICENSE-APACHE)
Based on the excellent work insql-formatter-plus.
About
SQL Formatter written in Rust
Resources
License
Apache-2.0, MIT licenses found
Licenses found
Uh oh!
There was an error while loading.Please reload this page.