QoreDB LogoQoreDB
Back to blog
VisionTechnical journal

Why QoreDB doesn't translate queries between engines

When you build a multi-engine database client, the temptation to offer a unified language is strong. A universal SQL that would work everywhere, from PostgreSQL to MongoDB by way of Redis. The idea is appealing on paper. In practice, it produces fragile abstractions that hide the…

Raphaël – Creator of QoreDBRaphaël – Creator of QoreDB
4 min readUpdated Jul 18, 2026
Why QoreDB doesn't translate queries between engines

When you build a multi-engine database client, the temptation to offer a unified language is strong. A universal SQL that would work everywhere, from PostgreSQL to MongoDB by way of Redis. The idea is appealing on paper. In practice, it produces fragile abstractions that hide the real behavior of each engine.

QoreDB made the opposite choice from the start. Every query is sent as-is to the target engine. No translation, no rewriting, no abstraction layer between what the developer writes and what the database receives. Here's why.

Every engine has its own grammar

PostgreSQL and MySQL share a SQL syntax on the surface, but diverge deeply as soon as you go beyond the basic SELECT. Window functions, recursive CTEs, JSON types, regular expressions, schema handling: each engine has its own conventions, its own keywords, its own implicit behaviors.

MongoDB isn't even in the same paradigm. Its query language is a JSON aggregation pipeline, not SQL. Redis works through key-value commands. Claiming to translate a PostgreSQL SELECT JOIN into a MongoDB pipeline would be approximate at best, and silently incorrect at worst.

A developer who works with PostgreSQL knows PostgreSQL. They expect to write PostgreSQL and to get PostgreSQL behavior. Serving them an approximate translation takes away their control over what actually runs.

Unification happens at the right level

Not translating queries doesn't mean everything is siloed. QoreDB unifies the experience at a structural level, not a syntactic one. The DataEngine trait in Rust defines a common interface that each driver implements: connect, disconnect, list namespaces, list collections, execute queries, stream results. This interface lets the UI offer consistent navigation across all engines without ever touching the query itself.

The data model uses three universal concepts: Namespace, Collection, Record. A PostgreSQL schema and a MongoDB database are both Namespaces. A table and a collection are Collections. This minimal abstraction is enough to build a unified navigation tree, a consistent tab system, and metadata panels that work everywhere.

The contract is clear: QoreDB unifies navigation and display, not the query language.

What transparency brings day to day

When a developer runs a query in QoreDB, they know exactly what goes to the server. If the query fails, the error message comes straight from the engine, not from an intermediate layer that would have reformulated the query and produced an incomprehensible error. Debugging stays direct.

The SQL editor's autocomplete is also contextual. It suggests the functions and syntax of the connected engine, not a generic subset. Query templates are tailored to each driver. An INSERT template for PostgreSQL uses RETURNING *, the one for MySQL doesn't, because MySQL doesn't support it.

This fidelity to the engine also shows up in the exposed features. The DataEngine trait uses default implementations for optional capabilities. If an engine doesn't support routines or sequences, the driver doesn't pretend to support them. The interface adapts: menu entries disappear, panels don't show up. No fake button that would return an error.

Federation as a contained exception

QoreDB offers a cross-database federation feature that lets you join data coming from different connections. This federation relies on DuckDB as the local execution engine. Data is extracted from each source through the native driver, then fed into DuckDB to be joined there in standard SQL.

This is the only situation where QoreDB runs SQL that isn't the source engine's. And this exception is explicit: the user knows they are in a federation context, with its own rules. Each source's original query stays intact. DuckDB operates only on the retrieved results, not on the remote databases.

In practice: an editor that respects the engine

Connected to PostgreSQL, the editor offers PostgreSQL syntax. Connected to MongoDB, it switches to a JSON editor with support for the aggregation syntax. Query cancellation uses pg_cancel_backend on PostgreSQL, KILL QUERY on MySQL, and a best-effort mechanism on MongoDB. Data export uses the native types of each engine.

Every interaction reflects the real workings of the underlying engine. The developer can copy a query from QoreDB, paste it into a psql or mongosh terminal, and get exactly the same result. There is no vendor lock-in at the language level.

A choice that trusts the developer

Not translating queries is a choice of trust. QoreDB assumes the developer knows their engine and wants a tool that helps them work faster with it, not a tool that gets in between them and their database. The product's intelligence focuses on what surrounds the query: navigation, autocomplete, security, result display, export. The query itself remains the developer's territory.

It's this stance that lets QoreDB support engines as different as PostgreSQL and Redis in the same application, without compromising on the fidelity of each one.

Newsletter

Stay updated on new releases

Subscribe to get product releases, new drivers notifications, and technical tutorials.

🎁 Bonus: Get our free SQL Performance Cheat Sheet — 9 pages, PostgreSQL / MySQL / SQLite (PDF)!
Share
Why QoreDB doesn't translate queries between engines - Blog - QoreDB