sqllens-language-server
A multi-dialect SQL language server built on sqllens,
the TypeScript SQL parser and static analyzer. The server is a thin Language Server
Protocol (LSP) adapter: it maps editor requests to the library's passes (parse → lower → resolveScopes → qualify → infer → symbols) and translates the results into
LSP shapes. It holds no analysis logic of its own: diagnostics, types, definitions,
output columns, tokens, completions, and signatures all come from the library.
Source-first and semantics-first: the server understands SQL statically, across ten
real dialects, without a database connection. Schema knowledge is optional and file-fed;
with it you get semantic diagnostics, typed hover, and schema-aware completion, and
without it the syntax tiers keep working.
Dialects: databricks, tsql, snowflake, bigquery, redshift, postgres,
duckdb, trino, sqlite, mysql.
Install and run
npm install -g sqllens-language-server
sqllens-language-server --stdio
The server speaks LSP over stdio (the --stdio flag is required). It is meant to be
launched by an editor / LSP client, not used interactively from a terminal.
Feature status
The server holds one session per open file (rebuilt on edit) and serves every feature
from that cached document. Every feature carries real source positions (no count-only
or point-only output), and the interactive features work on mid-edit / invalid input.
A SQL server needs only a subset of LSP's ~30 request types: some don't apply to
SQL (type hierarchy, document color, monikers), and a few are deferred (formatting,
project-wide navigation). Where the server stands today, feature by feature:
Language features
| Feature | Status |
|---|
| Completion (+ resolve) | ✅ |
| Hover | ✅ |
| Hover — nullability | ✅ ( — not null / — nullable suffix when provable) |
| Signature help | ✅ |
| Go to definition | ✅ |
| Find references | ✅ |
| Document highlight | ✅ |
| Document symbols | ✅ |
| Folding range | ✅ |
| Selection range | ✅ |
| Semantic tokens (full / range / delta) | ✅ all three |
| Inlay hints | ✅ (no resolve) |
| Code lens | ✅ (no resolve) |
| Go to declaration | ◻️ not yet |
| Go to type definition | ◻️ not yet |
| Go to implementation | ◻️ not yet — name → its defining query (view / model); needs the project model |
| Call hierarchy | ◻️ not yet — the CTE / view / model dependency graph |
| Document link | ◻️ not yet |
| Linked editing range | ◻️ not yet — live alias / name sync-edit |
| Code action (quick fixes) | ✅ for .sqllens.json (change-dialect fixes) · ◻️ SQL quick fixes next phase |
| Rename (+ prepare) | ◻️ next phase |
| Formatting / range / on-type | ◻️ deferred (external formatter) |
| Inline values | ◻️ debugger surface |
| Type hierarchy | — n/a — SQL has no type-inheritance relation |
| Document color | — n/a — no color literals |
| Moniker | — n/a — LSIF / cross-repo indexing concern |
Diagnostics & document sync
| Feature | Status |
|---|
Diagnostics — push (publishDiagnostics) | ✅ |
| Diagnostics — call signature (arity / argument type) | ✅ (curated tables; never-wrong, per-dialect coercion) |
| Diagnostics — pull (document) | ✅ |
| Diagnostics — pull (workspace) | ◻️ not yet |
| Text sync — open / change / close | ✅ (full-document) |
| Incremental sync | ◻️ full-document only (fine at SQL file sizes) |
Save notifications (didSave / willSave) | ◻️ not yet |
| Notebook document sync | ◻️ not yet |
Workspace features
| Feature | Status |
|---|
| Workspace symbols | ◻️ needs a project / multi-file model |
| Execute command | ◻️ not yet |
| Configuration / watched-files | ✅ .sqllens.json validates + reloads live while open in the editor · ◻️ OS file watch / protocol config not yet |
| File operations (create / rename / delete) | ◻️ not yet |
Legend: ✅ implemented · ◻️ not yet / deferred · — not applicable to SQL. The
deferred items are tracked work: rename and code actions are the next LSP phase,
workspace symbols need the project model, and formatting is expected to wrap an
existing external formatter.
Dialect and schema config: .sqllens.json
A document's dialect is configured, never guessed. On initialize, the server reads
.sqllens.json from the workspace root. It holds an ordered list of glob rules
(first match wins), an optional default, and an optional schema catalog. A missing
or malformed config is non-fatal: every file falls back to the databricks dialect
and a warning is logged over the LSP window/logMessage channel.
Example .sqllens.json:
{
"dialects": [
{ "files": "warehouse/snowflake/**/*.sql", "dialect": "snowflake" },
{ "files": "edw/**/*.sql", "dialect": "tsql" }
],
"default": "databricks",
"schema": "schema.json"
}