-
Notifications
You must be signed in to change notification settings - Fork 7
Closed
Labels
Description
Problem
GoSQLX has 10 linter rules (L001–L010). Bytebase has 200+; SQLFluff's growth to 9,600 stars is driven primarily by its linter. 30 rules is the threshold for CI pipeline adoption — below this, teams treat the linter as a style formatter; above it, teams integrate it as a mandatory gate.
Target Rules (L011–L030)
Category: Dangerous Operations (L011–L015)
| Rule | Name | Severity | Description |
|---|---|---|---|
| L011 | DELETE without WHERE | Error | DELETE FROM users without WHERE clause — full table wipe risk |
| L012 | UPDATE without WHERE | Error | UPDATE users SET active=0 without WHERE — bulk mutation risk |
| L013 | DROP TABLE safety | Error | DROP TABLE without IF EXISTS and outside a transaction hint |
| L014 | TRUNCATE safety | Warning | TRUNCATE TABLE without preceding analysis comment |
| L015 | SELECT * in production | Warning | SELECT * — breaks on schema changes, transfers unnecessary data |
Category: Performance Anti-Patterns (L016–L020)
| Rule | Name | Severity | Description |
|---|---|---|---|
| L016 | Leading wildcard LIKE | Warning | WHERE name LIKE '%foo' — full table scan, can't use B-tree index |
| L017 | Function on indexed column | Warning | WHERE UPPER(name) = 'X' — prevents index usage |
| L018 | Implicit cross join | Warning | FROM a, b without WHERE join condition — Cartesian product risk |
| L019 | OR conditions vs IN | Info | WHERE x=1 OR x=2 OR x=3 — suggest WHERE x IN (1,2,3) |
| L020 | NOT IN with NULLs | Warning | WHERE x NOT IN (SELECT y FROM t) — returns empty if y has NULLs |
Category: Naming Conventions (L021–L025)
| Rule | Name | Severity | Description |
|---|---|---|---|
| L021 | Table alias required | Info | Joins without table aliases reduce readability |
| L022 | Ambiguous column reference | Warning | Column not qualified in multi-table query |
| L023 | Reserved word as identifier | Warning | Using SQL keyword as table/column name without quoting |
| L024 | Implicit NULL semantics | Info | Comparison col = NULL instead of IS NULL |
| L025 | Inconsistent quoting | Info | Mix of quoted and unquoted identifiers in same statement |
Category: Schema Safety (L026–L030)
| Rule | Name | Severity | Description |
|---|---|---|---|
| L026 | Missing PRIMARY KEY | Warning | CREATE TABLE without PRIMARY KEY constraint |
| L027 | NOT NULL without DEFAULT | Info | NOT NULL column without DEFAULT value (insertion risk) |
| L028 | Implicit column default | Info | Column without explicit NULL/NOT NULL declaration |
| L029 | CHAR vs VARCHAR | Info | CHAR type causes space padding; prefer VARCHAR |
| L030 | Unbounded VARCHAR | Info | VARCHAR without length limit (dialect-specific risk) |
Implementation Notes
- Rules should be configurable: enable/disable per rule, set severity overrides
- Config format: extend existing .gosqlx.yml
- All rules must have auto-fix where applicable (L011 → suggest
WHERE 1=0as safe placeholder; L019 → auto-convert to IN) - Add
--rule L011,L016flag togosqlx lintfor targeted checking - Add MCP tool
lint_sql_rulesthat accepts a rule list parameter
Acceptance Criteria
- 20 new rules implemented (L011–L030)
- Each rule: detect + test + auto-fix where applicable
- 95%+ coverage on new rule code
- docs/LINTING_RULES.md updated with all 30 rules
-
gosqlx lint --rules L011,L016flag support - CI example:
.github/workflows/sql-lint.yml
Reactions are currently unavailable