sqlsift-lsp
v0.1.4
Published
LSP server for SQL static analysis against schema definitions
Maintainers
Readme
sqlsift
SQL static analyzer that validates queries against schema definitions — no database connection required.
sqlsift parses your DDL files (CREATE TABLE, CREATE VIEW, CREATE TYPE, ALTER TABLE, etc.) and validates SQL queries at build time, catching errors like missing tables, unknown columns, and typos before they reach production.
Note: sqlsift is in early development (alpha). APIs and diagnostics may change between versions. Feedback and contributions are welcome!
Features
- Zero database dependency — Works entirely offline using schema SQL files
- Framework agnostic — Works with Rails, Prisma, raw SQL migrations, and more
- Helpful diagnostics — Clear error messages with suggestions for typos
- CI-ready — JSON and SARIF output formats for integration with CI/CD pipelines
- Fast — Built in Rust for speed
Installation
via npm (Recommended)
npm install -g sqlsift-cliOr use directly with npx:
npx sqlsift-cli check --schema schema.sql query.sqlvia Cargo
cargo install sqlsift-cliFrom GitHub Releases
Download the latest binary from Releases.
Quick Start
# Validate queries against a schema file
sqlsift check --schema schema.sql queries/*.sql
# Use multiple schema files
sqlsift check -s users.sql -s orders.sql queries/*.sql
# Use a migrations directory
sqlsift check --schema-dir ./migrations queries/*.sqlExample
Given a schema:
-- schema.sql
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email TEXT UNIQUE
);And a query with errors:
-- query.sql
SELECT naem, user_id FROM users;sqlsift will report:
error[E0002]: Column 'naem' not found
= help: Did you mean 'name'?
error[E0002]: Column 'user_id' not foundFramework Integration
Prisma
Prisma generates SQL migration files automatically:
sqlsift check --schema-dir prisma/migrations queries/*.sqlRails
With config.active_record.schema_format = :sql:
sqlsift check --schema db/structure.sql queries/*.sqlOr with SQL migrations:
sqlsift check --schema-dir db/migrate queries/*.sqlRaw SQL
Just point to your schema files:
sqlsift check --schema schema/*.sql queries/**/*.sqlDiagnostic Rules
| Code | Name | Description | Status | |------|------|-------------|--------| | E0001 | table-not-found | Referenced table does not exist in schema | ✅ Implemented | | E0002 | column-not-found | Referenced column does not exist in table | ✅ Implemented | | E0003 | type-mismatch | Type incompatibility in expressions (comparisons, arithmetic) | ✅ Implemented | | E0004 | potential-null-violation | Potential NOT NULL violation (explicit NULL assignment) | ✅ Implemented | | E0005 | column-count-mismatch | INSERT column count doesn't match values | ✅ Implemented | | E0006 | ambiguous-column | Column reference is ambiguous across tables | ✅ Implemented | | E0007 | join-type-mismatch | JOIN condition compares incompatible types | ✅ Implemented |
Type Inference Coverage (E0003, E0007)
Currently Detected:
- ✅ WHERE clause comparisons (
WHERE id = 'text') - ✅ Arithmetic operations (
SELECT name + 10) - ✅ JOIN conditions (
ON users.id = orders.user_name) - ✅ Set operations column validation (
UNION/INTERSECT/EXCEPTcolumn count and type compatibility) - ✅ Potential NOT NULL violation checks for explicit
NULLassignment inINSERT/UPDATE(E0004) - ✅ INSERT value type mismatches (
INSERT INTO users (id) VALUES ('text')) - ✅ UPDATE assignment type mismatches (
UPDATE users SET id = 'text') - ✅ CAST expression type inference (
CAST(name AS INTEGER)) - ✅ Function return type inference (e.g.,
COUNT,SUM,UPPER,LENGTH,COALESCE) - ✅ Nested expressions (
WHERE (a + b) * 2 = 'text') - ✅ All comparison operators (=, !=, <, >, <=, >=)
- ✅ Numeric type compatibility (INTEGER, BIGINT, DECIMAL, etc.)
Not Yet Detected:
- ⏳ CASE expression type consistency
- ⏳ Subquery/CTE column type inference
Inline Suppression
Suppress diagnostics on specific lines using SQL comments:
-- Suppress a specific rule on the next line
-- sqlsift:disable E0002
SELECT legacy_col FROM users;
-- Suppress on the same line
SELECT legacy_col FROM users; -- sqlsift:disable E0002
-- Suppress multiple rules
SELECT bad_col FROM missing_table; -- sqlsift:disable E0001, E0002
-- Suppress all rules on the next line
-- sqlsift:disable
SELECT bad_col FROM missing_table;CLI Reference
sqlsift check [OPTIONS] <FILES>...
Arguments:
<FILES>... SQL files to validate (supports glob patterns)
Options:
-s, --schema <FILE> Schema definition file (can be specified multiple times)
--schema-dir <DIR> Directory containing schema files
-c, --config <FILE> Path to configuration file [default: sqlsift.toml]
--disable <RULE> Disable specific rules (e.g., E0001, E0002)
-d, --dialect <NAME> SQL dialect [default: postgresql]
-f, --format <FORMAT> Output format: human, json, sarif [default: human]
--max-errors <N> Maximum number of errors before stopping [default: 100, 0 = unlimited]
-v, --verbose Enable verbose logging (-vv for debug)
-q, --quiet Suppress summary/non-error output
-h, --help Print helpOutput Formats
Human (default)
error[E0002]: Column 'user_id' not found in table 'users'
--> queries/fetch.sql:3:12
|
3 | WHERE users.user_id = $1
| ^^^^^^^^^
|
= help: Did you mean 'id'?JSON
sqlsift check -s schema.sql -f json queries/*.sqlSARIF (for GitHub Code Scanning)
sqlsift check -s schema.sql -f sarif queries/*.sql > results.sarifCI Integration
GitHub Actions
Add sqlsift to your CI pipeline to catch SQL errors in pull requests:
# .github/workflows/sqlsift.yml
name: SQL Lint
on: [push, pull_request]
jobs:
sqlsift:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npx sqlsift-cli check --schema schema.sql queries/*.sqlGitHub Code Scanning (SARIF)
Upload results to GitHub's Security tab:
# .github/workflows/sqlsift.yml
name: SQL Lint
on: [push, pull_request]
jobs:
sqlsift:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- uses: actions/checkout@v4
- run: npx sqlsift-cli check -s schema.sql -f sarif queries/*.sql > results.sarif
continue-on-error: true
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarifSupported SQL Queries
- SELECT, INSERT, UPDATE, DELETE with full column/table validation
- JOINs (INNER, LEFT, RIGHT, FULL, CROSS, NATURAL) with ON/USING clause validation
- CTEs (WITH clause) including recursive CTEs
- Subqueries (WHERE IN/EXISTS, FROM derived tables, scalar subqueries)
- LATERAL vs non-LATERAL scope isolation
- UPDATE ... FROM / DELETE ... USING (PostgreSQL extensions)
- Window functions (OVER, PARTITION BY, FILTER)
- GROUPING SETS, CUBE, ROLLUP
- DISTINCT ON, UNION / INTERSECT / EXCEPT
- ORDER BY with SELECT alias support
- Comprehensive expression coverage (CASE, CAST, JSON operators, AT TIME ZONE, ARRAY, etc.)
Supported DDL
CREATE TABLE(columns, constraints, primary keys, foreign keys, UNIQUE)CREATE VIEW(column inference from SELECT projection)CREATE TYPE AS ENUMALTER TABLE(ADD/DROP/RENAME COLUMN, ADD CONSTRAINT, RENAME TABLE)CHECKconstraints (column-level and table-level)GENERATED AS IDENTITYcolumns (ALWAYS / BY DEFAULT)- Resilient parsing — unsupported DDL (functions, triggers, domains, etc.) is gracefully skipped
Supported SQL Dialects
- PostgreSQL (default) — fully supported
- MySQL — supported (
--dialect mysql) - SQLite — supported (
--dialect sqlite)
Use the --dialect flag to specify the dialect.
Roadmap
Completed
- [x] Configuration file (
sqlsift.toml) - [x] MySQL dialect support
- [x] SQLite dialect support
- [x] Type inference for expressions (WHERE, JOIN, arithmetic, INSERT/UPDATE)
- [x] LSP server for editor integration (VS Code extension)
Planned
- [ ] CASE expression type consistency checking
- [ ] Subquery/CTE column type inference
- [ ] Custom rule plugins
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Run tests (
cargo test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- sqlparser-rs — SQL parsing
- miette — Diagnostic rendering
- clap — CLI framework
