Skip to content

P1: Expand linter from 10 to 30 rules — enable CI pipeline adoption #445

@ajitpratap0

Description

@ajitpratap0

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=0 as safe placeholder; L019 → auto-convert to IN)
  • Add --rule L011,L016 flag to gosqlx lint for targeted checking
  • Add MCP tool lint_sql_rules that 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,L016 flag support
  • CI example: .github/workflows/sql-lint.yml

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High priorityenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions