xlg-sqlfmt

Crates.ioxlg-sqlfmt
lib.rsxlg-sqlfmt
version0.2.0
created_at2025-09-24 18:39:43.670612+00
updated_at2025-09-24 21:19:59.452423+00
descriptionA command-line SQL formatter that reads SQL from stdin and writes formatted SQL to stdout
homepagehttps://github.com/xlgmokha/sqlfmt
repositoryhttps://github.com/xlgmokha/sqlfmt
max_upload_size
id1853568
size50,281
mo khan (xlgmokha)

documentation

https://docs.rs/sqlfmt

README

xlg-sqlfmt

A fast, reliable SQL formatter written in Rust that reads SQL from stdin and writes beautifully formatted SQL to stdout.

Crates.io Documentation License: MIT

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:

  1. Output the original, unmodified SQL to stdout
  2. 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
Commit count: 0

cargo fmt