Good SQL Formatting
Optimize your queries for readability. A fast, opinionated formatter with a Monaco-grade editor and CLI-friendly workflows.
GoogleSQLPostgreSQLMySQLSnowflake+10 dialects
BigQuery (GoogleSQL)•1 lines•0 charsReady
Format from anywhere
Integrate formatting into your workflow — as simple as piping a file through curl. No install, no config.
BigQuery · sensible defaults
cat query.sql | curl -X POST --data-binary @- https://api.nidoran.work/format-sql
live · matches the options above
cat query.sql | curl -X POST \ --data-binary @- \ "https://api.nidoran.work/format-sql?dialect=bigquery&max_length=120&keyword_handling=upper_case&builtin_function_handling=lower_case&indent_cte_definitions=true&always_break_select=false&always_break_query=true&always_break_pipe=true"
Agent skill — format-sql/SKILL.md
Drop into .agents/skills/ to let agents format SQL automatically.
--- name: format-sql description: Format a SQL script using the silos formatting API. Pipe SQL text via curl to format with dialect, line length, and casing options. argument-hint: 'path to .sql file, e.g. query.sql' --- # Format SQL Use this skill when the user asks to format, beautify, or prettify a SQL query. ## Command ```bash cat query.sql | curl -X POST --data-binary @- "https://api.nidoran.work/format-sql?dialect=bigquery&max_length=120&keyword_handling=upper_case" ``` Pipe the SQL file contents to the API. The response is returned as plain text. ## Important Caveats ### Comments may be dropped The API does not always retain SQL comments. When formatting a query that contains comments (single-line `--` or block `/* */`), compare the original SQL with the formatted output. If comments were dropped, you must re-wire them back into the formatted SQL at the appropriate locations. Preserve the original comment text and place it logically near the code it was annotating. ### Error responses The API returns `text/plain` for both success and error cases. Check the response content: - If it starts with `Error:` or `error code:`, formatting failed — report the error reason to the user rather than treating it as formatted SQL. - A successful response is raw formatted SQL with no prefix. ### Minor syntax fixes If the API returns a syntax error, you may make **minimal, non-semantic fixes** to the SQL and retry formatting. Allowed fixes: - Add or adjust `AS` aliases (e.g. `unnest(...) x` → `unnest(...) AS x`) - Fix missing or trailing commas in SELECT, GROUP BY, etc. - Fix trivial keyword casing inconsistencies - Balance unmatched parentheses or quotes - Fix keyword typos (e.g. `SELEC` → `SELECT`) Do **not** make changes that alter the query's semantics, logic, or results. When in doubt, show the user the error and ask how they'd like to fix it. ## Available Options (query parameters) | Parameter | Type | Default | Description | | --------------------------- | ------------------------------- | -------------- | --------------------------------------------------------------------------------------------------------- | | `dialect` | string | `"bigquery"` | SQL dialect. GooglesQL dialects: `"bigquery"`, `"googlesql"`. Any other value falls through to sqlfusion. | | `max_length` | int | `120` | Maximum line length before the formatter wraps | | `keyword_handling` | `"upper_case"` / `"lower_case"` | `"upper_case"` | Case for SQL keywords (SELECT, FROM, WHERE, etc.) | | `builtin_function_handling` | `"upper_case"` / `"lower_case"` | `"upper_case"` | Case for builtin functions (COUNT, SUM, etc.) | | `indent_cte_definitions` | bool | `true` | Indent CTE definitions | | `always_break_select` | bool | `false` | Always put each select item on its own line | | `always_break_query` | bool | `false` | Always put each query clause on its own line | | `always_break_pipe` | bool | `false` | Always break pipe operators to separate lines | ### Notes - **GooglesQL dialects** (`"bigquery"`, `"googlesql"`): all options above are supported. - **Other dialects** (sqlfusion fallback): only `dialect` and `max_length` apply. The dialect value is passed directly to sqlfusion (e.g. `"postgresql"`, `"mysql"`, `"sqlite"`, `"duckdb"`, `"databricks"`, etc.). ### Bool parameter values Accepted truthy values: `"true"`, `"1"`, `"yes"`, `"on"` (case-insensitive). Anything else is falsy. ### Default request (no options) ```bash cat query.sql | curl -X POST --data-binary @- "https://api.nidoran.work/format-sql" ``` This formats as GooglesQL/BigQuery with `max_length=120` and `keyword_handling=upper_case`. ### Examples Format with lower-case keywords and 80-char line length: ```bash cat query.sql | curl -X POST --data-binary @- "https://api.nidoran.work/format-sql?keyword_handling=lower_case&max_length=80" ``` Format as Postgres: ```bash cat query.sql | curl -X POST --data-binary @- "https://api.nidoran.work/format-sql?dialect=postgresql&max_length=100" ```
Under the hood
Two parsers, full AST formatting, broad dialect coverage.
most complete
GoogleSQL (BigQuery)
Parsed with Google’s own GoogleSQL engine into an abstract syntax tree before formatting rules are applied — including scripts and pipe syntax.
everything else
DataFusion parser
All other dialects use the DataFusion SQL parser. It covers most dialects well; a few unusual dialect-specific features may not parse.
Supported dialects
ANSI SQLBigQuery (GoogleSQL)ClickHouseDatabricksDuckDBGeneric SQLHiveMS SQLMySQLOraclePostgreSQLRedshiftSQLiteSnowflake