Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>sqldexNew to Visual Studio Code? Get it now.
sqldex

sqldex

SQLDex

|
5 installs
| (0) | Free
Static analysis for MySQL schemas that live as .sql files in a repository.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

sqldex for VS Code

Gotta index 'em all!

A repository full of CREATE TABLE and CREATE PROCEDURE files is a database schema, and this makes VS Code read it as one. Open a stored procedure and every table in the project is already known — its columns, their types, which ones are nullable, where each foreign key leads, and the values a one-letter status column is allowed to hold. No database connection, no credentials, nothing running: the catalog is built from the .sql files themselves.

What that buys you is the answer to the questions a schema repository raises all day. What is c.doc_type and what can it hold. Which table is d again. Who else writes to this table. What would this rename touch. All of it is a keypress, and none of it is a text search.

If you have used DataGrip's DDL data source — point the IDE at a directory of .sql files and it builds a schema out of them, so navigation and inspections work with no database running — that is the idea this comes from, in VS Code, with a rule set written specifically for MySQL. The longer version is in the project's own README.

What you get, and how to reach it

VS Code maps all of it to what you already press:

The column under the cursor, in full — its type, whether it is nullable, whether it is a primary or unique key, and the table its foreign key points at. Plus its DEFAULT, its COMMENT, and the values it is allowed to hold: the set the comment documents, or, where nobody wrote one down, the codes the procedures are seen comparing it against hover
The table under the cursor — its CREATE TABLE, exactly as the repository has it hover
What a two-letter alias stands for, and what a temporary table holds and which file created it hover
Findings as you type — 39 rules over names, schema, queries and routines: a column that does not exist, an INSERT whose value count does not match, an UPDATE with no filter, a variable never read, a foreign key with no index the Problems panel and the squiggles; F8 walks them
Where a name is defined, and where its foreign key leads F12, and Ctrl+F12 for the foreign key's target
Everywhere a table or column is used — whole identifiers, so searching orders does not also hand you aud_orders Shift+F12
Rename it across the project, definition and uses together F2 — this extension's own rename, see below
Statements written from the catalog — expand a * into the columns it stands for, generate a SELECT, an INSERT or an UPDATE over the table under the cursor, add the columns an audit twin is missing, or rewrite a table's audit triggers Ctrl+.
Outline, and every name in the project Ctrl+Shift+O, and Ctrl+T
What a routine calls, and who calls it right-click → Peek → Call Hierarchy
Completion that knows the schema — the columns of the alias you just typed a dot after, the tables in the project, a routine's parameters as you type; o. opens the list
Column types, what an alias stands for, and a CALL's parameter names, inline inlay hints, on unless you turned them off globally

Editing .sqldex.json gets completion and validation of its own, from a schema this extension contributes: the keys, the five rule groups, the severities, and the shape of a rule id. Rule ids are deliberately not enumerated in it — a list of them here would be one more copy to keep in step with the engine, and a stale one would flag a rule that exists. sqldex rules prints the current list, and sqldex explain <id> prints one rule's whole reasoning.

Everything above comes from the sqldex-lsp language server; this extension is the client that starts it, and it implements no feature of its own. What is here is the three questions a client has to answer — how to start the server, for which documents, and which directory is the project — plus one that only a multi-root editor has to ask. What gets reported is never decided here: it lives in the project's own .sqldex.json, the same file sqldex check reads in CI.

What you need

  • VS Code 1.91 or newer, which is what the language client library needs.
  • Node 22.18 or newer on your PATH, which is what the server runs on.
  • The server, which an installed .vsix already contains. A checkout finds its own, and a sqldex-lsp you installed yourself wins over both.

Installing

From the Extensions view — Ctrl+Shift+X, search sqldex — or

code --install-extension sqldex.sqldex

It carries the server with it, which is what makes it worth installing on a machine that has never seen this repository — see below. What it does not carry is Node: the machine installing it needs Node 22.18 or newer on its PATH, and the extension says so in a notification rather than failing quietly if it finds an older one.

That is also what decides how a new rule reaches you. The engine is inside the extension, so a version of the engine is a version of the extension: rules arrive when VS Code updates it, which it does on its own. The exception is a sqldex-lsp you installed yourself — it wins over the bundled copy, and then npm update -g @sqldex/lsp is what brings the rule and the extension has nothing to do with it.

Without the marketplace

A .vsix is a file, and building one from a checkout is two commands:

cd editors/vscode
npm install
npm run package      # downloads vsce on demand; leaves sqldex-<version>.vsix beside this file

That file is the thing to hand to somebody else — an air-gapped machine, a fork, a version that was never released. They install it with code --install-extension sqldex-<version>.vsix, or through the Extensions view: the … menu, Install from VSIX.

To work on the client itself, skip all of that: open this directory in VS Code and press F5, or

code --extensionDevelopmentPath="$PWD/editors/vscode" ~/src/your-schema-repo

Nothing has to be configured either way. The extension wakes when a .sql file is opened or a .sqldex.json is in the tree, and starts a server only for folders that are schema projects.

Rename, and why it has a command of its own

F2 here runs sqldex: Rename symbol rather than the editor's built-in rename, and that is deliberate.

VS Code picks one provider for a rename. For the prepare step it walks the registered providers and stops at the first one that does not implement it, falling back to the plain word under the cursor; for the edit it takes the first provider that answers with anything at all, an empty answer included. Which provider comes first is decided by which one registered last, so with two SQL language servers in the same window it is a race — and the other ones commonly declare renameProvider: true without the prepare half, take the request, and answer with nothing.

The result is a rename that opens its input box, accepts a name, and changes nothing, with no error anywhere. If you have sqls, SQLTools or another SQL server installed, that is what you would get about half the time.

The command does not enter the race: it asks the server this extension started and applies what comes back. To give F2 back to the editor, unbind it in your own keybindings:

{ "key": "f2", "command": "-sqldex.rename" }

Settings

Two, and neither is about analysis:

sqldex.server.path the command to start, when it is not sqldex-lsp from your PATH
sqldex.trace.server log the protocol traffic into the sqldex output channel

There is deliberately no setting for what gets reported. Severities, which rules run and which directories are sources all live in the project's .sqldex.json, which is the same file sqldex check reads in CI — because a rule that is off in one place and on in the other is a rule nobody trusts. A user setting here would be exactly that disagreement, one machine at a time.

What is in the package, and why it is source

The .vsix contains the client, its language client library, and the server itself — the packages/core and packages/lsp sources, copied into server/. An extension that only knew how to find a server somebody else installed would be an extension that does nothing when installed, and nothing is published to npm for that somebody to install from.

Source, not a build: the server is TypeScript that Node runs by stripping the types, which is why this repository has no build step and why what ships is what is in packages/. npm run package copies it and rewrites exactly one thing — the @sqldex/core import, which a node_modules would have answered and here has to be a relative path.

That is the reason server/ is not laid out as a node_modules, and it is worth knowing before "tidying" it: Node refuses to strip types from a file under node_modules, so an extension packaged that way installs perfectly and then dies at the first import with ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING.

Where the server comes from, in the order the extension tries:

sqldex.server.path somebody named a file
sqldex-lsp on the PATH somebody installed one
the checkout above this directory somebody cloned the repository — and beats the bundle, since the bundle is a copy taken from it
server/ inside the extension what an installed .vsix runs

The sqldex output channel says which of the four it used, every time it starts one.

One server per project, not per window

The server is single-root by design: it reads one folder and builds one catalog, because answering across two projects from one catalog would mean a name in one resolving against a table in the other. So a window with three schema repositories in it gets three servers, each with its own root.

Two folders that turn out to be inside the same repository share one server — otherwise every finding would arrive twice — and a folder opened below the root still gets the whole project's answers, because the root is found by walking up from the folder, exactly as the engine does.

A folder that is not a schema project gets no process at all, and the output channel says which one and why. That guard is the reason the extension can activate on any .sql file without indexing a repository that merely happens to contain one.

Why it watches files

The server asks the client to watch **/*.sql and the config file, and this client obliges without being asked twice — VS Code creates the watchers from the server's own registration.

It matters more than it sounds. The catalog is built from what is on disk, and updated one file at a time when you save. A branch switch rewrites hundreds of .sql files without one of them passing through an editor, and every answer afterwards would come from a schema that is no longer there.

If your repository is large and you have narrowed files.watcherExclude, note that it applies here too: a directory VS Code does not watch is one the server is never told about.

When nothing happens

The sqldex output channel, first. It has both sides in it: this client's line about what it started and why, the server's own line about which project it built and how much is in it — or why it built nothing, which is the answer worth reading when the extension started something and the answers still come back empty — and, if the server could not be started at all, the error, which also arrives as a notification.

If the client says the folder is not a schema project, that is the guard above. A project is a directory holding .sqldex.json, tablas/, sp/, or tables/ beside sps/ or functions/. An empty .sqldex.json at the root is enough to declare one.

If nothing was started at all, the extension never woke: it activates on a .sql file being opened or a .sqldex.json in the tree, and a window with neither gives it no reason to.

sqldex: Restart the language server in the command palette picks up a project that came into existence after the window was opened — a .sqldex.json you just wrote, a tables/ you just made.

It is also the answer to a rule that fires everywhere except here. Installing a new version of the extension does not restart the server the window is already running, so a window left open across an upgrade keeps the old engine until it is told otherwise. The startup line in the output channel ends with a rule count for exactly this: if it disagrees with sqldex rules, the process is older than the files it came from.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft