Rust/Wasm-powered SQL transpiler for 32+ dialects, inspired by sqlglot.
Polyglot parses, generates, transpiles, and formats SQL across 32+ database dialects. It ships as:
- a Rust crate (
polyglot-sql) - a TypeScript/WASM SDK (
@polyglot-sql/sdk) - a Python package (
polyglot-sql)
There's also a playground where you can try it out in the browser, as well as Rust API Docs, TypeScript API Docs, and Python API Docs.
Release notes are tracked in CHANGELOG.md.
- Transpile SQL between any pair of 32 dialects
- Parse SQL into a fully-typed AST
- Generate SQL back from AST nodes
- Format / pretty-print SQL
- Fluent builder API for constructing queries programmatically
- Validation with syntax, semantic, and schema-aware checks
- AST visitor utilities for walking, transforming, and analyzing queries
- C FFI shared/static library for multi-language bindings (
polyglot-sql-ffi) - Python bindings powered by PyO3 (
polyglot-sqlon PyPI)
| Athena | BigQuery | ClickHouse | CockroachDB | Databricks |
| Doris | Dremio | Drill | Druid | DuckDB |
| Dune | Exasol | Fabric | Hive | Materialize |
| MySQL | Oracle | PostgreSQL | Presto | Redshift |
| RisingWave | SingleStore | Snowflake | Solr | Spark |
| SQLite | StarRocks | Tableau | Teradata | TiDB |
| Trino | TSQL |
use polyglot_sql::{transpile, DialectType}; // Transpile MySQL to PostgreSQL let result = transpile( "SELECT IFNULL(a, b) FROM t", DialectType::MySQL, DialectType::Postgres, ).unwrap(); assert_eq!(result[0], "SELECT COALESCE(a, b) FROM t");use polyglot_sql::builder::*; // Fluent query builder let query = select(["id", "name"]) .from("users") .where_(col("age").gt(lit(18))) .order_by(["name"]) .limit(10) .build();See the full Rust crate README for more examples.
npm install @polyglot-sql/sdkimport { transpile, Dialect } from '@polyglot-sql/sdk'; // Transpile MySQL to PostgreSQL const result = transpile( 'SELECT IFNULL(a, b) FROM t', Dialect.MySQL, Dialect.PostgreSQL, ); console.log(result.sql[0]); // SELECT COALESCE(a, b) FROM timport { select, col, lit } from '@polyglot-sql/sdk'; // Fluent query builder const sql = select('id', 'name') .from('users') .where(col('age').gt(lit(18))) .orderBy(col('name').asc()) .limit(10) .toSql('postgresql');See the full TypeScript SDK README for more examples.
pip install polyglot-sqlimport polyglot_sql result = polyglot_sql.transpile( "SELECT IFNULL(a, b) FROM t", read="mysql", write="postgres", ) print(result[0]) # SELECT COALESCE(a, b) FROM tSee the full Python bindings README.
SQL formatting runs through guard limits in Rust core to prevent pathological inputs from exhausting memory:
maxInputBytes:16 MiB(default)maxTokens:1_000_000(default)maxAstNodes:1_000_000(default)maxSetOpChain:256(default)
Guard failures return error codes in the message (E_GUARD_INPUT_TOO_LARGE, E_GUARD_TOKEN_BUDGET_EXCEEDED, E_GUARD_AST_BUDGET_EXCEEDED, E_GUARD_SET_OP_CHAIN_EXCEEDED).
Configuration surface by runtime:
- Rust: configurable via
format_with_options. - WASM: configurable via
format_sql_with_options/format_sql_with_options_value. - TypeScript SDK: configurable via
formatWithOptions. - C FFI: configurable via
polyglot_format_with_options. - Python: configurable via keyword-only
format_sql(..., max_*)overrides.
WASM low-level example (from polyglot-sql-wasm exports):
import init, { format_sql_with_options } from "./polyglot_sql_wasm.js"; await init(); const raw = format_sql_with_options( "SELECT a,b FROM t", "generic", JSON.stringify({ maxInputBytes: 2 * 1024 * 1024, maxTokens: 250000, maxAstNodes: 250000, maxSetOpChain: 128 }), ); const result = JSON.parse(raw);polyglot/ ├── crates/ │ ├── polyglot-sql/ # Core Rust library (parser, generator, builder) │ ├── polyglot-sql-function-catalogs/ # Optional dialect function catalogs (feature-gated data) │ ├── polyglot-sql-wasm/ # WASM bindings │ ├── polyglot-sql-ffi/ # C ABI bindings (.so/.dylib/.dll + .a/.lib + header) │ └── polyglot-sql-python/ # Python bindings (PyO3 + maturin, published on PyPI) ├── packages/ │ ├── sdk/ # TypeScript SDK (@polyglot-sql/sdk on npm) │ ├── documentation/ # TypeScript API documentation site │ ├── playground/ # Playground for testing the SDK (React 19, Tailwind v4, Vite) │ └── python-docs/ # Python API documentation site (Cloudflare Pages) ├── examples/ │ ├── rust/ # Rust example │ ├── typescript/ # TypeScript SDK example │ └── c/ # C FFI example └── tools/ ├── sqlglot-compare/ # Test extraction & comparison tool └── bench-compare/ # Performance benchmarks Standalone example projects are available in the examples/ directory. Each one pulls the latest published package and can be run independently.
cargo run --manifest-path examples/rust/Cargo.tomlcd examples/typescript pnpm install --ignore-workspace && pnpm start# Build Rust core cargo build -p polyglot-sql # Build C FFI crate (shared/static libs + generated header) cargo build -p polyglot-sql-ffi --profile ffi_release # Build Python extension / wheel make develop-python make build-python # Build WASM + TypeScript SDK make build-all # Or step by step: cd crates/polyglot-sql-wasm && wasm-pack build --target bundler --release cd packages/sdk && npm run buildPolyglot provides a stable C ABI in crates/polyglot-sql-ffi.
- Crate README:
crates/polyglot-sql-ffi/README.md - Generated header:
crates/polyglot-sql-ffi/polyglot_sql.h - Example program:
examples/c/main.c - Make targets:
make build-ffimake generate-ffi-headermake build-ffi-examplemake test-ffi
For tagged releases (v*), CI also attaches prebuilt FFI artifacts and checksums to GitHub Releases.
Polyglot provides first-party Python bindings in crates/polyglot-sql-python.
- Crate README:
crates/polyglot-sql-python/README.md - Package name on PyPI:
polyglot-sql - Make targets:
make develop-pythonmake test-pythonmake typecheck-pythonmake build-python
Optional dialect function catalogs are provided via crates/polyglot-sql-function-catalogs.
- Crate README:
crates/polyglot-sql-function-catalogs/README.md - Core feature flags:
function-catalog-clickhousefunction-catalog-duckdbfunction-catalog-all-dialects
- Intended behavior: compile-time inclusion, one-time load in core, auto-use during schema validation type checks.
Polyglot currently runs 10,220 SQLGlot fixture cases plus additional project-specific suites. All strict pass/fail suites are at 100% in the latest verification run.
| Category | Count | Pass Rate |
|---|---|---|
| SQLGlot generic identity | 956 | 100% |
| SQLGlot dialect identity | 3,554 | 100% |
| SQLGlot transpilation | 5,513 | 100% |
| SQLGlot transpile (generic) | 145 | 100% |
| SQLGlot parser | 29 | 100% |
| SQLGlot pretty-print | 23 | 100% |
| Lib unit tests | 835 | 100% |
| Custom dialect identity | 276 | 100% |
| Custom dialect transpilation | 347 | 100% |
| ClickHouse parser corpus (non-skipped) | 7,047 | 100% |
| FFI integration tests | 20 | 100% |
Python bindings tests (make test-python) | 69 | 100% |
| Total (strict Rust/FFI pass/fail case count) | 18,745 | 100% |
# Setup fixtures (required once) make setup-fixtures # Run all tests make test-rust-all # All SQLGlot fixture suites make test-rust-lib # Lib unit tests (835) make test-rust-verify # Full strict verification suite make test-ffi # FFI crate integration tests # Individual test suites make test-rust-identity # 956 generic identity cases make test-rust-dialect # 3,554 dialect identity cases make test-rust-transpile # 5,513 transpilation cases make test-rust-transpile-generic # 145 generic transpile cases make test-rust-parser # 29 parser cases make test-rust-pretty # 23 pretty-print cases # Additional tests make test-rust-roundtrip # Organized roundtrip unit tests make test-rust-matrix # Dialect matrix transpilation tests make test-rust-compat # SQLGlot compatibility tests make test-rust-errors # Error handling tests make test-rust-functions # Function normalization tests # TypeScript SDK tests cd packages/sdk && npm test # Full comparison against Python SQLGlot make test-comparemake bench-compare # Compare polyglot-sql vs sqlglot performance make bench-rust # Rust benchmarks (JSON output) make bench-python # Python sqlglot benchmarks (JSON output) cargo bench -p polyglot-sql # Criterion benchmarkscargo +nightly fuzz run fuzz_parser cargo +nightly fuzz run fuzz_roundtrip cargo +nightly fuzz run fuzz_transpile| Target | Description |
|---|---|
make help | Show all available commands |
make build-all | Build core release + FFI + Python + bindings + WASM/SDK |
make build-wasm | Build WASM package + TypeScript SDK |
make build-ffi | Build C FFI crate (ffi_release profile) |
make generate-ffi-header | Generate C header via cbindgen/build.rs |
make build-ffi-example | Build + run C example against FFI lib |
make develop-python | Build/install Python extension in uv-managed env |
make build-python | Build Python wheels with maturin |
make test-ffi | Run FFI integration tests |
make test-rust | Run SQLGlot-named Rust tests in polyglot-sql |
make test-rust-all | Run all 10,220 SQLGlot fixture cases |
make test-rust-lib | Run 835 lib unit tests |
make test-rust-verify | Full verification suite |
make test-rust-clickhouse-parser | Run strict ClickHouse parser suite |
make test-rust-clickhouse-coverage | Run ClickHouse coverage suite (report-only) |
make test-compare | Compare against Python sqlglot |
make bench-compare | Performance comparison |
make bench-rust-parsing-report | Run rust_parsing bench and generate Markdown report |
make bench-parse | Core parse benchmark (polyglot vs sqlglot) |
make bench-parse-quick | Faster core parse benchmark mode |
make bench-parse-full | Parse benchmark including optional parsers |
make extract-fixtures | Regenerate JSON fixtures from Python |
make setup-fixtures | Create fixture symlink for Rust tests |
make generate-bindings | Generate TypeScript type bindings |
make test-python | Run Python bindings tests |
make typecheck-python | Run Python bindings type-check |
make documentation-build | Build documentation site |
make documentation-deploy | Deploy documentation to Cloudflare Pages |
make python-docs-build | Build Python API docs site |
make python-docs-deploy | Deploy Python API docs to Cloudflare Pages |
make playground-build | Build playground |
make playground-deploy | Deploy playground to Cloudflare Pages |
make clean | Remove all build artifacts |
For a release-note friendly summary of the pure Rust parse benchmark (short, long, tpch, crazy), run:
make bench-rust-parsing-reportThis will:
- run
cargo bench -p polyglot-sql --bench rust_parsing - read Criterion results from
target/criterion/rust_parse_quick_equivalent/parse_one - generate
target/criterion/rust_parsing_report.mdwith a Markdown table (mean, std dev, 95% CI, baseline delta if available)
Latest generated result snapshot:
- Generated: 2026-02-26 13:43:10 UTC
- Source:
target/criterion/rust_parse_quick_equivalent/parse_one
| Query | Mean | Std Dev | 95% CI (mean) | Change vs baseline |
|---|---|---|---|---|
| short | 51.28 us | 481.03 ns | 51.09 us - 51.60 us | -8.40% |
| long | 259.61 us | 666.53 ns | 259.23 us - 260.01 us | -5.21% |
| tpch | 268.59 us | 776.85 ns | 268.15 us - 269.07 us | -0.03% |
| crazy | 1.03 ms | 66.07 us | 992.65 us - 1.07 ms | +6.05% |