SQL Glyph
Decipher. Transform. Transpile.
SQL Glyph is a local-first VS Code extension that uses SQLGlot to parse SQL into an AST, transpile it between ten dialects, explain the structural changes, report compatibility risks, and show a native diff — without connecting to a database or executing a single query.
Why SQL Glyph
- AST-powered, not regex-powered. Every conversion is parsed and generated by SQLGlot. SQL Glyph never rewrites SQL with search-and-replace rules.
- Honest about uncertainty. Warnings are separated from hard unsupported cases. Transformations without a matching rule are labeled
unexplained instead of inventing a reason.
- Local by design. SQL stays on your machine. There is no backend, no telemetry, no database connection, and no query execution.
- Native VS Code workflows. Problems panel diagnostics, a native diff editor, copy/replace/save actions, an AST explorer, and a conversion analysis panel.
Features
- Convert a selection or an entire SQL file.
- Transpile between PostgreSQL, MySQL, T-SQL, Snowflake, BigQuery, Oracle, SQLite, DuckDB, Spark SQL, and Trino.
- Multi-statement input and SQLGlot pretty printing.
- Conservative source-dialect auto detection with a confirmation prompt when the result is ambiguous.
- Structured parser and generation errors, including source spans.
- AST Explorer with searchable, collapsible nodes, properties, generated SQL, comments, and source spans.
- Native diff editor comparing the original input with the converted SQL.
- Conversion Analysis panel with:
- SUCCESS / WARNING / UNSUPPORTED status
- compatibility diagnostics grouped by category
- rule-based transformation explanations with confidence and review state
- line-level diff
- engine and processing metadata
- Explicit replace confirmation. Replacing SQL is always a modal, undoable edit.
- Copy result, open result, and save-as actions.
- Problems panel diagnostics published to the source document.
- Setup flow for a private managed Python environment. Dependencies are never installed silently.
Supported dialects
| Identifier |
Display name |
Notes |
postgres |
PostgreSQL |
:: casts, SERIAL, JSONB, RETURNING, NULLS FIRST/LAST |
mysql |
MySQL |
Backtick identifiers, AUTO_INCREMENT, LIMIT; null ordering may be emulated with CASE |
tsql |
Microsoft SQL Server (T-SQL) |
TOP, OFFSET … FETCH, bracket identifiers; COUNT_BIG may appear |
snowflake |
Snowflake |
QUALIFY, IFF, VARIANT, upper-case folding |
bigquery |
Google BigQuery |
Backticks, STRUCT/ARRAY, SAFE_CAST, QUALIFY |
oracle |
Oracle Database |
FROM DUAL, NVL, ROWNUM, CONNECT BY, FETCH FIRST |
sqlite |
SQLite |
PRAGMA, AUTOINCREMENT, function-based date handling |
duckdb |
DuckDB |
List/struct types, READ_CSV, QUALIFY |
spark |
Spark SQL |
LATERAL VIEW, DISTRIBUTE BY, complex types |
trino |
Trino |
ARRAY, TRY_CAST, ANSI joins |
The Python dialect registry is authoritative for engine capabilities. The TypeScript registry mirrors display metadata, and integration tests assert that both lists contain the same ten identifiers.
Requirements
- VS Code 1.90 or newer
- Python 3.9 or newer for the local engine
- SQLGlot 30.31.0 (installed by the setup flow or supplied by your interpreter)
- No database driver, database account, or network connection is needed for conversion
Tested with VS Code 1.143.1, Node.js 22.11.0, Python 3.12.6, and SQLGlot 30.31.0.
Installation
From a VSIX
code --install-extension sql-glyph-0.1.0.vsix
Then reload VS Code.
First run
- Open the SQL Glyph activity-bar view or run SQL Glyph: Set Up Local Engine.
- Choose a Python 3.9+ interpreter. SQL Glyph creates a private virtual environment under its global storage directory and installs
sqlglot==30.31.0 there.
- Alternatively, set
sqlGlyph.pythonPath to an interpreter that already has SQLGlot installed.
The setup flow asks before creating an environment and before installing anything. It requires network access only for the explicit pip install step.
Commands
| Command |
Description |
| SQL Glyph: Convert Selected SQL |
Convert the current selection and open a native diff |
| SQL Glyph: Convert Entire File |
Convert the whole SQL document |
| SQL Glyph: Inspect AST |
Parse the selection (or the whole file) and open the AST Explorer |
| SQL Glyph: Compare Dialects |
Convert the selection or file and open the analysis panel plus diff |
| SQL Glyph: Show Conversion Analysis |
Open the analysis panel for the most recent conversion |
| SQL Glyph: Select Source Dialect |
Choose a concrete source dialect or Auto Detect |
| SQL Glyph: Select Target Dialect |
Choose the target dialect |
| SQL Glyph: Open Conversion Panel |
Focus the SQL Glyph sidebar view |
| SQL Glyph: Set Up Local Engine |
Create/repair the managed Python environment |
| SQL Glyph: Show Engine Output |
Show the local engine log |
Commands are available from the Command Palette, the SQL editor context menu, and the SQL Glyph sidebar.
Using SQL Glyph
Convert and review
- Open a
.sql file and select part of it, or select nothing to convert the whole file.
- Run Convert Selected SQL or Convert Entire File.
- SQL Glyph parses the input, generates the target dialect, and opens a native diff.
- Use the notification or sidebar actions to copy the result, open the analysis, replace the source (with confirmation), or save a new file.
The Replace action is always a modal confirmation. It checks that the source text has not changed since conversion, applies a normal undoable editor edit, and clears stale diagnostics.
Auto detection
When the source dialect is auto:
- A high-confidence heuristic result proceeds and shows a notification.
- Medium/low confidence, or
sqlGlyph.autoDetectBehavior = "alwaysAsk", opens a quick pick with the candidate dialects and evidence.
- If no markers are found, SQL Glyph asks you to choose manually. It never silently assumes an ambiguous dialect.
Detection is a heuristic based on dialect markers plus SQLGlot parseability. It is not proof of the source dialect.
AST Explorer
The AST Explorer shows the SQLGlot parse tree with:
- node type, label, description, and generated SQL
- grouped child roles such as
From, Where, Expressions, and Joins
- primitive properties
- comments
- source spans with a Reveal action
- search/filter across types, labels, properties, and SQL
- node and depth limits with an explicit truncation notice
Conversion Analysis
The analysis panel separates:
- Diagnostics — compatibility risks and errors, with category, rule ID, confidence, and source location.
- Transformations — syntactic rewrites observed between the source and target. Each item shows the original and converted snippet, a rule-based explanation when one exists, and
unexplained when it does not.
- Text diff — a line-level diff of the input and generated SQL.
- Metadata — dialect pair, statement count, elapsed time, SQLGlot/engine versions, and the explicit flags
executed: false, databaseConnected: false, and semanticallyVerified: false.
Diagnostics and status
SQL Glyph uses three overall conversion statuses:
| Status |
Meaning |
| SUCCESS |
SQLGlot parsed and generated the SQL and no compatibility diagnostics were raised. This still does not prove semantic equivalence. |
| WARNING |
SQL was generated, but one or more compatibility risks were detected. Review the analysis before using the output. |
| UNSUPPORTED |
SQLGlot generated output that is known to be unsupported or invalid for the target, or the request failed. The output must not be used without review. |
Diagnostic severities are error, warning, and info. A conversion can return success: true at the protocol level while the overall status is unsupported; this lets the extension display the generated SQL and the reason it is unsafe.
Configuration
| Setting |
Default |
Description |
sqlGlyph.pythonPath |
"" |
Path to a Python 3.9+ interpreter. Empty means use the managed environment or a detected python3/python. |
sqlGlyph.defaultSourceDialect |
auto |
Source dialect or conservative auto detection. |
sqlGlyph.defaultTargetDialect |
bigquery |
Target dialect. |
sqlGlyph.prettyPrint |
true |
Format generated SQL with SQLGlot's pretty printer. |
sqlGlyph.maxSqlSizeKb |
2048 |
Maximum SQL input size in KB. The engine enforces a 10 MB hard limit. |
sqlGlyph.engineTimeoutMs |
30000 |
Timeout for one local engine request. |
sqlGlyph.showConversionDiagnostics |
true |
Publish conversion diagnostics to the Problems panel. |
sqlGlyph.autoDetectBehavior |
notify |
Proceed on high-confidence detection (notify) or always ask (alwaysAsk). |
Privacy and security
- SQL is sent to a local Python subprocess over stdin/stdout using newline-delimited JSON. It is never uploaded.
- The engine has no database code, no network code, and no SQL execution code. It only calls SQLGlot parsing and generation APIs.
- The extension has zero runtime npm dependencies.
- No telemetry is collected.
- The only network access is the explicit
pip install sqlglot==30.31.0 performed by Set Up Local Engine, and only after confirmation.
- Setup is disabled in untrusted workspaces. Conversion can still use an already-installed engine.
- Webviews use a strict Content Security Policy, a nonce, and local resources only.
Limitations
SQL Glyph is a syntax transpiler and analyzer, not a migration validator.
- No execution and no semantic verification. Generated SQL is never run, compared against a database, or checked for equivalent results.
- SQLGlot coverage is finite. Vendor-specific syntax, user-defined functions, extensions, and newer database features may be parsed as anonymous functions or rejected.
- Not all rewrites are valid for the target. SQL Glyph flags known cases, but the diagnostic rules are conservative and incomplete.
- Known SQLGlot outputs to review:
- PostgreSQL → BigQuery date arithmetic may produce nested
INTERVAL (INTERVAL …) expressions.
- PostgreSQL → T-SQL intervals may appear as
INTERVAL '1' DAY, which T-SQL does not accept.
- PostgreSQL → Oracle/SQLite date truncation may emit
TIMESTAMP_TRUNC, which those engines do not provide.
SERIAL may leak into BigQuery output.
MERGE may be emitted for MySQL or SQLite, which do not support it.
- T-SQL output may remove the
RECURSIVE keyword, emit COUNT_BIG(*), or emulate null ordering with CASE.
- BigQuery may add explicit
NULLS FIRST/LAST.
- Same-dialect formatting can still rewrite unsupported constructs.
- Auto detection is heuristic. Shared syntax is common; confirm the source dialect when precision matters.
- Session state is not simulated. Multi-statement files are parsed and generated statement by statement. Temporary tables, variables, transactions, and DDL dependencies are not tracked.
- Comments and formatting can move. SQLGlot may reorder or normalize whitespace and comments.
- Statement splitting is SQLGlot's. Dialect-specific batch separators such as T-SQL
GO are not treated as a session boundary.
- Size limits. The default input limit is 2 MB and the engine hard limit is 10 MB.
If a conversion matters, review the analysis panel and test the generated SQL against the target database in your normal migration workflow.
Development
Repository layout
src/ TypeScript extension
engine/ Python discovery, process lifecycle, JSONL bridge
services/ conversion, AST, diagnostics, dialects, previews
views/ sidebar webviews, analysis panel, status bar
webview/ CSP-safe HTML builder
types/ protocol, dialect, AST, conversion types
media/ icons and vanilla JS/CSS webviews
sql-engine/ Python engine and pytest suite
test/ Vitest unit/integration tests and shared fixtures
Architecture
VS Code extension host (TypeScript)
│ newline-delimited JSON over stdin/stdout
▼
Python 3.9+ subprocess (sql-engine/main.py)
│
▼
SQLGlot 30.31.0 — parse, generate, format
The Python engine is authoritative for dialect capabilities, diagnostics, transformation rules, AST serialization, and detection. The TypeScript layer owns VS Code integration, editor state, webviews, and process lifecycle.
Build and test
npm install
npm run compile # typecheck + esbuild bundle
npm run typecheck
npm test # Python + Vitest unit + real bridge integration
npm run test:python
npm run test:unit
npm run test:integration
The Python tests can also be run directly:
cd sql-engine
python -m pytest
Integration tests start the real Python engine and exercise the JSONL protocol, shared dialect fixtures, AST serialization, detection, and error envelopes.
Package
npm run package:vsix
This produces sql-glyph-0.1.0.vsix. The VSIX contains the bundled extension, the Python engine, webview assets, icons, README, CHANGELOG, and LICENSE.
Verification
The 0.1.0 release was verified with:
- 106 Python engine tests, 68 Vitest unit tests, and 41 real bridge integration tests.
- A 28-file VSIX installed with
code --install-extension into a clean --extensions-dir on VS Code 1.143.1, reported as sqlglyph.sql-glyph@0.1.0.
- A smoke test of the installed engine from an unrelated working directory:
health, transpile, inspect_ast, and shutdown all returned successful protocol responses with SQLGlot 30.31.0 on Python 3.12.6.
Troubleshooting
“No Python 3.9+ interpreter was found.”
Install Python 3.9+ and ensure it is on PATH, set sqlGlyph.pythonPath, or run SQL Glyph: Set Up Local Engine and browse for the interpreter.
“SQLGlot is not installed.”
Run SQL Glyph: Set Up Local Engine. SQL Glyph does not install packages into an existing interpreter silently.
The engine times out.
Increase sqlGlyph.engineTimeoutMs, convert a smaller selection, or check SQL Glyph: Show Engine Output. A timed-out request restarts the engine process.
A conversion is marked UNSUPPORTED.
Open Show Conversion Analysis, read the error diagnostics, and review the generated SQL manually. The extension intentionally does not hide or “fix” invalid output.
Setup cannot reach PyPI.
Configure your normal proxy environment variables or point sqlGlyph.pythonPath at an interpreter where SQLGlot 30.31.0 is already installed.
License
MIT. See the LICENSE file included with the extension.
SQL Glyph is an independent project. SQLGlot is a separate open-source project with its own license.
| |