Dependency-free (stdlib-only) static analyzer that enforces DB-agnostic SQL (MySQL/MariaDB + PostgreSQL) in a Go codebase. Because it imports nothing outside the standard library, it runs in any Go module — GoatFlow itself or a standalone GoatKit plugin / product repo — without coupling to a shared codebase.
PostgreSQL rejects SQL that is valid only on MySQL. Two classes break it:
- MySQL-only statements —
ON DUPLICATE KEY UPDATE,INSERT IGNORE,REPLACE INTO— which PostgreSQL rejects and which cannot be ported without a real unique/primary key target. - Raw
?placeholders on a raw database method (Exec/Query/QueryRow/ExecContext/QueryContext/QueryRowContext). PostgreSQL expects$N. Host API methods (host.DBExec/host.DBQuery) are exempt: the host converts placeholders at runtime.
Both checks honour dialect-guarded branches — the body of if X.IsMySQL() { ... }
and the else of if X.IsPostgreSQL() { ... } (any receiver X) are legitimate
MySQL.
# against the current repo (default dir "."):
go run github.com/goatkit/sql-lint@latest .
# with a baseline of pre-existing violations (see below):
go run github.com/goatkit/sql-lint@latest -baseline gk-sql-lint.baseline .Exits 0 when clean, 1 on violation.
A --baseline file (one path:line per line, # comments allowed) lets you adopt
the lint on a codebase with pre-existing MySQL-only code: baseline entries are
suppressed, so the check passes today while still failing on any NEW MySQL-only
SQL. Regenerate with:
go run github.com/goatkit/sql-lint@latest . 2>&1 \
| sed -nE 's/^ [a-z-]+: ([^ ]+):([0-9]+).*/\1:\2/p' | sort -u > gk-sql-lint.baselineAdd to Makefile:
lint-sql:
go run github.com/goatkit/sql-lint@latest -baseline gk-sql-lint.baseline .and add the same step to CI.