Skip to content

feat(rules): report queries that cannot do what they appear to - #15

Merged
kvlonge merged 2 commits into
mainfrom
feat/safety-rules
Oct 31, 2026
Merged

kvlonge merged 2 commits into
mainfrom
feat/safety-rules

Conversation

@kvlonge

@kvlonge kvlonge commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

Why

The safety review found mistakes SQLClean misses even with every Rule selected: duplicate CTE names, WHEN NULL, literal-zero division, reversed BETWEEN, aggregates in WHERE, NATURAL JOIN, and unguarded writes.

Changes

Eight report-only Rules in sql_quality/_helpers/safety.rs. The AST decides statement and CTE facts and which names are aggregates; tokens locate findings exactly.

  • Default: SQC046 duplicate CTE names (dialect-aware quoting and case, per WITH scope), SQC047 CASE x WHEN NULL and singleton IN (NULL), SQC048 /, %, //, MOD by a literal zero, SQC051 NATURAL JOIN, SQC052 reversed number or ISO date BETWEEN bounds (NOT reported, SYMMETRIC skipped), SQC053 aggregates or windows in WHERE, ON, GROUP BY.
  • Opt-in: SQC049 UPDATE/DELETE with no row-reading predicate, join condition or LIMIT (WHERE TRUE counts as none), SQC050 INSERT without columns (DEFAULT VALUES, BY NAME pass).
  • Docs: Rule reference table and section, counts 45 to 53, regenerated skill.

Default runs can report new findings on code with these mistakes.

Verification

  • make verify, integration and e2e suites, website build, fensu 0 faults.
  • One table of 23 cases, including controls such as BETWEEN 9 AND 10, 1e-400, quoted Postgres names, nested WITH, FILTER (WHERE ...), QUALIFY, SQLite max(a, b). Mutating the GROUP BY comma handling fails the test.
  • 10,282-file Snowflake corpus: default and all-Rules finding counts unchanged (3,872 and 34,322), so no false positives; default check 0.62 s to 0.64 s.
  • CLI end to end: each default Rule reports at the expected line; opt-in Rules only when selected.

Add eight report-only Rules on the parsed statements and tokens:
duplicate CTE names (SQC046), CASE WHEN NULL and IN (NULL) (SQC047),
literal-zero division (SQC048), unfiltered UPDATE or DELETE (SQC049,
opt-in), INSERT without a column list (SQC050, opt-in), NATURAL JOIN
(SQC051), reversed literal BETWEEN bounds (SQC052) and aggregates or
windows in WHERE, ON or GROUP BY (SQC053).
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Deploying sqlclean with  Cloudflare Pages  Cloudflare Pages

Latest commit: c3d2c65
Status: ✅  Deploy successful!
Preview URL: https://2b24ed50.sqlclean.pages.dev
Branch Preview URL: https://feat-safety-rules.sqlclean.pages.dev

View logs

@kvlonge
kvlonge merged commit ec34b41 into main Oct 31, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant