3 unstable releases
Uses new Rust 2024
| 0.2.0 | Sep 24, 2025 |
|---|---|
| 0.1.1 | Sep 24, 2025 |
| 0.1.0 | Sep 24, 2025 |
#968 in Database interfaces
36 downloads per month
37KB
809 lines
xlg-sqlfmt
A fast, reliable SQL formatter written in Rust that reads SQL from stdin and writes beautifully formatted SQL to stdout.
Features
- Fast and reliable - Built with Rust for maximum performance
- Stdin/stdout interface - Perfect for shell pipelines and editor integration
- Idempotent formatting - Running the formatter multiple times produces identical output
- Comprehensive SQL support - Handles complex queries with subqueries, CTEs, JOINs, and more
- Smart formatting - Single-line SELECT for simple projections, multi-line for complex ones
- Proper AND/OR formatting - Each logical operator on its own line with correct indentation
- Comment preservation - Maintains your SQL comments in their proper positions
- Error handling - On parse errors, outputs original SQL and exits with non-zero code
Installation
Using Cargo
cargo install xlg-sqlfmt
From Source
git clone https://github.com/xlgmokha/sqlfmt.git
cd sqlfmt
cargo install --path .
Usage
Basic Usage
# Format SQL from stdin
echo "select * from users where active=1" | xlg-sqlfmt
# Format a SQL file
xlg-sqlfmt < query.sql
# Format and save to file
xlg-sqlfmt < input.sql > formatted.sql
# Use in a pipeline
cat messy.sql | xlg-sqlfmt | less
Integration with Editors
Vim/Neovim
Add to your .vimrc or init.vim:
" Format SQL with xlg-sqlfmt
command! SQLFormat %!xlg-sqlfmt
Formatting Rules
SELECT Statements
Simple projections (single column or literal) are formatted on one line:
-- Input
SELECT 1 AS one FROM users WHERE active = true
-- Output
SELECT 1 AS one
FROM
users
WHERE active = TRUE;
Complex projections are formatted with each column on its own line:
-- Input
SELECT id, name, email, created_at FROM users
-- Output
SELECT
id,
name,
email,
created_at
FROM
users;
WHERE Clauses with AND/OR
Each logical operator starts a new line with proper indentation:
-- Input
SELECT * FROM users WHERE active = true AND age > 18 AND name LIKE 'A%'
-- Output
SELECT *
FROM
users
WHERE active = TRUE
AND age > 18
AND name LIKE 'A%';
JOINs
Each JOIN clause is on its own line, aligned properly:
-- Input
SELECT u.name, p.title FROM users u INNER JOIN posts p ON u.id = p.user_id LEFT JOIN comments c ON p.id = c.post_id
-- Output
SELECT
u.name,
p.title
FROM
users AS u
INNER JOIN posts AS p ON u.id = p.user_id
LEFT JOIN comments AS c ON p.id = c.post_id;
Subqueries
Subqueries are indented and recursively formatted:
-- Input
SELECT * FROM (SELECT id, name FROM users WHERE active = true) AS active_users WHERE name LIKE 'A%'
-- Output
SELECT *
FROM
(
SELECT
id,
name
FROM
users
WHERE active = TRUE
) AS active_users
WHERE name LIKE 'A%';
Common Table Expressions (CTEs)
-- Input
WITH active_users AS (SELECT * FROM users WHERE active = true) SELECT * FROM active_users
-- Output
WITH
active_users AS (
SELECT *
FROM
users
WHERE active = TRUE
)
SELECT *
FROM
active_users;
CASE Expressions
-- Input
SELECT CASE WHEN age < 18 THEN 'minor' WHEN age >= 65 THEN 'senior' ELSE 'adult' END AS age_group FROM users
-- Output
SELECT
CASE
WHEN age < 18 THEN 'minor'
WHEN age >= 65 THEN 'senior'
ELSE 'adult'
END AS age_group
FROM
users;
Error Handling
If the SQL cannot be parsed, xlg-sqlfmt will:
- Output the original, unmodified SQL to stdout
- Exit with a non-zero exit code (1)
This makes it safe to use in pipelines and scripts:
# This will pass through invalid SQL unchanged
echo "INVALID SQL SYNTAX" | xlg-sqlfmt
echo $? # Returns 1
# Valid SQL will be formatted
echo "SELECT * FROM users" | xlg-sqlfmt
echo $? # Returns 0
Idempotent Formatting
Running xlg-sqlfmt multiple times on the same SQL produces identical output:
echo "SELECT * FROM users" | xlg-sqlfmt | xlg-sqlfmt | xlg-sqlfmt
# All three runs produce identical output
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Development
# Clone the repository
git clone https://github.com/xlgmokha/sqlfmt.git
cd sqlfmt
# Run tests
cargo test
# Run clippy for linting
cargo clippy
# Format code
cargo fmt
# Test the binary
echo "SELECT * FROM users" | cargo run
License
This project is licensed under the MIT License - see the LICENSE file for details.
Changelog
v0.1.1
- Added smart SELECT formatting (single-line for simple projections)
- Improved AND/OR formatting in WHERE clauses with proper indentation
- Better handling of complex expressions
v0.1.0
- Initial release
- Basic SQL formatting with stdin/stdout interface
- Support for SELECT, INSERT, UPDATE, DELETE statements
- Subquery and CTE formatting
- JOIN clause formatting
- CASE expression formatting
- Comment preservation
- Error handling with original SQL pass-through
Dependencies
~2.5MB
~50K SLoC