Skip to main content

Datoria · SQL, compiled

A query goes in whole.

Your SQL exactly as written — comments, casing, habits and all. dfmt is our free formatter: 43 dialects, native dbt and Jinja, idempotent. dquery is the compiler underneath it, licensable for products that need parsing, lineage, and types.

SQL dialects

43

Every common database, from one grammar.

dbt models formatted

26 943

Across 164 public projects.

Formatting errors

1

In the entire corpus, at any width.

AST node types

5 480

Typed and immutable, generated per dialect.

The engine · dquery

It is taken apart.

Into a lossless syntax tree — every token kept. One grammar in, a whole semantic stack out, and the tools cannot disagree about what your SQL means.

If your product is built on SQL — catalogues, governance, DSPM, ELT and migration tools, IDE plugins, agentic-SQL tools, engines that need a real SQL front end — dquery is the compiler underneath. Not publicly available; we are letting a small number of companies in early.

  1. 01

    Grammar

    One declarative definition. Pure data, no embedded functions.

  2. 02

    Parser & renderer

    Generated per dialect. 5,480 typed, immutable AST interfaces.

  3. 03

    Scope resolution

    Qualified references across nested CTEs, subqueries and lateral joins.

  4. 04

    Type inference

    Dialect-aware coercion, function signatures, nullable tracking.

  5. 05

    Column lineage

    One pass through JOINs, CTEs, window functions and star expansion.

  6. 06

    Optimiser

    Qualify, simplify, pushdown, unnest, merge, eliminate.

  7. 07

    dbt & Jinja

    A real Jinja evaluator. 164 public projects compile end to end.

  8. 08

    Error recovery

    Partial parses with precise positions. It never crashes on broken SQL.

dfmt · free forever

The part you can see.

dfmt is the first product we shipped on top of the Datoria compiler. No trial, no signup. The easiest way to show you what the compiler can do is to let you format some SQL with it.

  • 43 dialects — Snowflake, BigQuery, PostgreSQL, T-SQL, Spark, DuckDB, and more
  • Native Jinja — templates go through a real Jinja engine, not a regex pass
  • Adaptive — keeps your line breaks where you put them, normalises the rest
  • Idempotent — format(format(x)) = format(x), always
  • 26,943 models, 1 errors — across 164 public dbt projects
What you wrote
select o.customer_id, count(*) as n,
sum(o.total) as revenue from orders o
join customers c on c.id=o.customer_id
where o.status in ('paid','shipped')
and o.created_at >= '2026-01-01'
group by o.customer_id order by revenue desc
Formatted with dfmt
SELECT
o.customer_id,
count(*) AS n,
sum(o.total) AS revenue
FROM orders o
JOIN customers c
ON c.id = o.customer_id
WHERE o.status IN ('paid', 'shipped')
AND o.created_at >= '2026-01-01'
GROUP BY o.customer_id
ORDER BY revenue DESC

What it read

And the part you cannot.

To lay that query out, the compiler had to resolve every name, infer every type, and know which physical table each column came from. Here is what it had by the time it started printing.

SELECT
o.customer_id,bigint orders.customer_id
count(*) AS n,bigint derived, never null
sum(o.total) AS revenuenumeric(12,2) orders.total
FROM orders otable analytics.public.orders
JOIN customers ctable analytics.public.customers
ON c.id = o.customer_id
WHERE o.status IN ('paid', 'shipped')text 2 of 6 known values
GROUP BY o.customer_id

And it comes back whole

In every one of 43 dialects

Dialects that share a grammar share a colour. Adding the next one is a grammar change, not a new parser — which is why the list keeps growing.

BigQuery family

BigQueryCloud Spanner

PostgreSQL family

CockroachDBPostgreSQLYugabyteDB

DuckDB family

DuckDBMotherDuck

Spark SQL family

Apache HiveApache ImpalaDatabricks SQLSpark SQL

MySQL family

Apache DorisMariaDBMySQLPlanetScaleSingleStoreStarRocksTiDB

T-SQL family

Azure SynapseMicrosoft FabricT-SQL

Trino family

Amazon AthenaDuneSQLPrestoStarburstTrino

Standalone grammars

Amazon RedshiftANSI SQLClickHouseIBM DB2OracleSnowflakeSQLite

The backstory

Two engineers in Norway

That was three years ago, and it was the whole reason to start. We like functional programming and data infrastructure, and we like making tools other engineers actually want to use.

So we built a compiler. One declarative grammar generates specialised, JIT-optimised compilers for all 43 SQL dialects we support. Each produces a typed, immutable AST with over 5,480 node types. On top of that: scope resolution, column lineage, type inference, query optimisation, error recovery, and a full Jinja evaluator for dbt projects.

In our benchmarks it is faster than the hand-written Rust and C parsers we have measured against. It passes the official conformance suites for PostgreSQL's libpg_query and Google's ZetaSQL, and it compiles 164 public dbt projects (26,943 models) and traces 99.63% of their 523,838 output columns back to a physical source.

None of it is open source. It is the foundation of what we are building. dfmt is the piece you can use today.

Øyvind
Øyvind
Ingar
Ingar

What we are building next

Column lineage and semantic analysis you can verify. An LSP server so your IDE understands SQL the way the compiler does. An agent API for LLM-driven SQL tools. dfmt is the free preview; the rest is on the way.