You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit a37459b
Browse filesBrowse the repository at this point in the historyBrowse files
docs: restructure the README around the SQLBuild layout (#7)
* docs: restructure the README around the SQLBuild layout
Co-authored-by: Kevin Longe <kvlonge@gmail.com>
* docs: lead the README with speed and capabilities
Co-authored-by: Kevin Longe <kvlonge@gmail.com>
* docs: fill the README speed claim and table from the published benchmarks
Co-authored-by: Kevin Longe <kvlonge@gmail.com>
---------
Co-authored-by: Amp <amp@ampcode.com>
<strong>Clean SQL, every time.</strong> Fast linting, safe fixes and one canonical format.
8
+
<strong>50× faster than sqruff. Lint 10,000 SQL files in under a second.</strong> <ahref="https://sqlclean.io/docs/benchmarks/">Benchmarks</a>
7
9
</p>
8
10
9
-
SQLClean checks `.sql` files against built-in Rules, applies their fixes and formats every file in
10
-
one canonical layout. The engine and the `sqlclean` command are written in Rust. Custom Rules
11
-
are plain Python functions that read structural facts about each statement.
12
-
13
11
<palign="center">
14
-
<imgsrc=".github/demos/check-fix.gif"alt="sqlclean check reports three findings, then sqlclean fix applies two fixes and formats the file"width="100%">
12
+
Catch SQL mistakes, apply safe fixes, and format consistently. Add your own rules in Python.
15
13
</p>
16
14
17
-
`sqlclean check` reports a bare `JOIN`, a `COUNT(1)` and a temporary table from a custom Rule.
18
-
`sqlclean fix` applies the two fixes and formats the file; the custom Rule's finding has no fix,
The `sqlclean` package installs the native `sqlclean` executable. Custom Rules run in the same
29
-
Python environment as that executable.
26
+
<palign="center">
27
+
<imgsrc="https://raw.githubusercontent.com/sqlstack-io/sqlclean/main/.github/demos/check-fix.gif"alt="sqlclean check reports three findings, then sqlclean fix applies two fixes and formats the file"width="100%">
28
+
</p>
30
29
31
-
## Commands
30
+
`sqlclean check` reports a bare `JOIN`, a `COUNT(1)` and a temporary table from a custom Rule.
31
+
`sqlclean fix` applies the two fixes and formats the file; the custom Rule's finding has no fix,
32
+
so it stays.
32
33
33
-
```bash
34
-
sqlclean check [PATHS]... # report findings; exit 1 when there are any
35
-
sqlclean fix [PATHS]... # apply safe fixes until stable, then format
36
-
sqlclean format [PATHS]... # rewrite files in the canonical layout
37
-
sqlclean rules [CODE] # list the Rules, or explain one
38
-
sqlclean skills # install the skill for AI coding agents
39
-
```
34
+
## Speed
40
35
41
-
- With no paths, a command reads every matching file under the configuration root.
42
-
-`check` and `fix` accept `--select` and `--ignore`, which take codes or prefixes such as
43
-
`SQC001` or `SQC`, and `--no-cache`.
44
-
-`check --output-format` takes `text`, `json` or `sarif`. Use SARIF for code-scanning uploads.
45
-
-`fix --unsafe-fixes` also applies fixes that can change query results. `fix --diff` and
46
-
`format --diff` print a unified diff instead of writing.
47
-
-`format --check` fails when a file needs formatting, without writing it.
48
-
- Exit status is 0 when clean, 1 when there are findings or files to change, and 2 on errors.
49
-
50
-
Each statement is formatted on its own. Statements are separated by one blank line, and every
51
-
file ends with a newline. Formatting is idempotent: a formatted file formats to itself.
52
-
53
-
## Configuration
54
-
55
-
SQLClean reads the nearest `sqlclean.toml` at or above the working directory, or the file passed
56
-
with `--config`. Paths in it are relative to the file's directory.
57
-
58
-
```toml
59
-
dialect = "duckdb"# default "generic"
60
-
include = ["**/*.sql"]
61
-
exclude = ["vendor/**"] # files ignored by .gitignore are skipped too
62
-
63
-
[[dialects]] # a different dialect for some paths
64
-
paths = ["warehouse/**"]
65
-
dialect = "snowflake"
66
-
67
-
[format]
68
-
line_width = 100
69
-
indent = 4
70
-
71
-
[rules]
72
-
select = ["SQC"] # omit to run the Rules enabled by default
73
-
ignore = ["SQC027"]
74
-
custom = ["sql_rules"] # Python files or directories that define custom Rules
75
-
76
-
[rules.thresholds]
77
-
max_literal_length = 100# SQC044
78
-
max_ranking_order_by = 5# SQC043
79
-
80
-
[rules.rule_options.XSQCNAME001]
81
-
prefixes = ["tmp_", "scratch_"]
82
-
83
-
[[rules.rule_exceptions]] # one reviewed finding that is allowed
84
-
rule = "SQC038"
85
-
path = "models/calendar.sql"
86
-
relation = "dates"# optional: the joined relation the CROSS JOIN reads
87
-
reason = "Every pair of dates is needed."
88
-
89
-
[[rules.rule_ignores]] # Rules that do not apply to some paths
90
-
rules = ["SQC034"]
91
-
paths = ["scratch/**"]
92
-
reason = "Exploratory queries."
93
-
```
36
+
Linting the same 10,282 Snowflake SQL files on 4 CPUs, with no cache:
94
37
95
-
An exception that no longer matches a finding is reported as stale, so exceptions are removed
96
-
when the SQL they cover changes. A parse error is reported as `SQC999` and cannot be ignored.
0 commit comments