Connectivity · 40 Types · 12 Dialects

Forty connection types. Twelve dialects. One query model.

Qrly speaks JDBC to twenty native engines and to the AWS, Azure and GCP managed variants, and compiles every query through the right dialect — quoting, pagination, NULL ordering and date bucketing included. Connections are read-only by default and credentials are encrypted at rest.

Native engines

Twenty engines with their own drivers

  • Transactional: PostgreSQL, MySQL, MariaDB, SQL Server, DB2, Sybase (jTDS), Pervasive
  • Warehouses: Snowflake, Redshift, BigQuery, Vertica, SingleStore
  • Analytical and federated: ClickHouse, DuckDB, Trino, Presto
  • Embedded and file-based: SQLite, H2, HSQLDB, Derby
Managed cloud

Each variant has its own type string

  • AWS: Aurora Postgres and MySQL, RDS Postgres, MySQL, MariaDB and SQL Server, Redshift, Athena
  • Azure: SQL, Synapse, Postgres, MySQL, MariaDB
  • GCP: Cloud SQL Postgres, MySQL and SQL Server, AlloyDB, BigQuery, Spanner
  • Recognised as themselves, so connection defaults and tooling can differ per platform
Not supported

No driver, no dependency, no pretending

  • Oracle, Teradata, SAP HANA, Cassandra, MongoDB, Dremio, Firebird — none has a driver in the build
  • CockroachDB is recognised by the dialect resolver but has no driver mapping
  • Older project notes list some of these; the shipping code does not
  • Reach them instead through Trino or Presto, or replicate into a supported target with table sync
Native engines
Engine Category Compiles as Notes
PostgreSQLTransactionalPOSTGRESThe reference dialect. Full-text search, JSONB, array and range operators, LISTEN/NOTIFY live dashboards, COPY ingest and logical-replication CDC
MySQLTransactionalMYSQLNULLS ordering emulated with (field IS NULL); binlog CDC; ON DUPLICATE KEY upsert
MariaDBTransactionalMARIADBIts own compiler rather than a MySQL alias; NULLS ordering emulated; binlog CDC
SQL ServerTransactionalSQLSERVERBracketed identifiers, OFFSET…FETCH NEXT, sp_rename staging swap, database-level CDC with per-table capture instances
SQLiteEmbeddedSQLITEAffinity-aware type classification; native upsert; NULLS ordering emulated. Week and quarter date buckets are rejected
H2EmbeddedH2Supports full-text search operators and OLAP grouping sets
HSQLDBEmbeddedH2Folds into the H2 compiler
DerbyEmbeddedH2Folds into the H2 compiler
DuckDBAnalyticalPOSTGRESWire-compatible, so it inherits the Postgres compiler
SnowflakeWarehouseSNOWFLAKEvariant and timestamp_ltz normalised by the type classifier; grouping sets supported; Constructions warns that Snowflake has no CREATE INDEX
RedshiftWarehouseREDSHIFTFull-text search, JSON, array and range operators; native COPY ingest; repeatable-read snapshots for FK group sync
BigQueryWarehouseBIGQUERYService-account key auth; struct and bytes normalised; grouping sets supported; staging swap falls back to drop, create and insert in one transaction
ClickHouseAnalyticalPOSTGRESWire-compatible, so it inherits the Postgres compiler
VerticaWarehousePOSTGRESWire-compatible, so it inherits the Postgres compiler
TrinoFederatedPOSTGRESReaches engines Qrly has no driver for, through one connection
PrestoFederatedPOSTGRESSame fold as Trino
SingleStoreWarehouseMYSQLMySQL wire protocol, so it inherits the MySQL compiler
DB2TransactionalDB2Its own compiler, including TRUNC_TIMESTAMP date bucketing
SybaseTransactionalSYBASEReached over jTDS. Rejects OFFSET, so pagination is TOP n only; NULLS ordering emulated
PervasiveTransactionalPERVASIVEIts own compiler
Twenty native engines. Unknown connection types default to the Postgres compiler, so an unrecognised JDBC source still runs rather than failing at compile time.
Managed-cloud variants
Platform Service Underlying engine Notes
AWSAurora PostgresPostgreSQLIts own connection type, so defaults and tooling can differ from a self-managed Postgres
AWSAurora MySQLMySQLIts own connection type
AWSRDS PostgresPostgreSQLIts own connection type
AWSRDS MySQLMySQLIts own connection type
AWSRDS MariaDBMariaDBIts own connection type
AWSRDS SQL ServerSQL ServerIts own connection type
AWSRedshiftRedshiftCompiles through the dedicated REDSHIFT dialect
AWSAthenaPresto-familyExplicitly folded into the POSTGRES compiler
AzureAzure SQLSQL ServerAuth modes include service principal, managed identity and AAD password
AzureSynapseSQL ServerAdds the Synapse tooling below — external tables and views, and generated OPENROWSET Delta Lake view DDL
AzureDatabase for PostgreSQLPostgreSQLIts own connection type
AzureDatabase for MySQLMySQLIts own connection type
AzureDatabase for MariaDBMariaDBIts own connection type
GCPCloud SQL for PostgreSQLPostgreSQLIts own connection type
GCPCloud SQL for MySQLMySQLIts own connection type
GCPCloud SQL for SQL ServerSQL ServerIts own connection type
GCPAlloyDBPostgreSQLIts own connection type
GCPBigQueryBigQueryCompiles through the dedicated BIGQUERY dialect; service-account key auth
GCPSpannerSpannerExplicitly folded into the POSTGRES compiler
Managed variants carry their own type strings rather than being aliased onto the self-managed engine, so Qrly knows which platform it is talking to.
01 / QUOTING

Identifier quoting

Double quotes on the Postgres family, backticks on MySQL and MariaDB, square brackets on SQL Server. Every table, column and alias Qrly emits is quoted for the target engine, and identifiers are regex-validated before they get anywhere near a statement, alongside a cast allow-list of thirty entries.

The twelve compilers are POSTGRES, MYSQL, MARIADB, SQLSERVER, BIGQUERY, SNOWFLAKE, REDSHIFT, SQLITE, H2, DB2, SYBASE and PERVASIVE.

02 / PAGINATION

LIMIT, FETCH or TOP

Three incompatible spellings for the same idea: LIMIT n OFFSET m on the Postgres and MySQL families, OFFSET m ROWS FETCH NEXT n ROWS ONLY on SQL Server and its managed variants, and TOP n where neither is available.

Sybase rejects OFFSET outright, so a query against it is compiled without one rather than being emitted and failing at the driver. The limit and offset in a QQL document are engine-independent; the compiler decides how to say them.

03 / NULL ORDERING

NULLS FIRST, NULLS LAST — or a workaround

QQL order-by carries ASC/DESC plus NULLS FIRST, NULLS LAST or the database default. Engines that support the clause natively get it verbatim.

Engines that do not — MySQL, MariaDB, SQLite and Sybase — get an automatic (field IS NULL) emulation expression prepended to the sort, so the result set is ordered identically whichever connection the question runs against. That matters the moment a question is repointed at a different environment.

04 / DATE BUCKETING

Year, quarter, month, week, day, hour

Six bucket levels compiled per engine with the right function: DATE_TRUNC, DATETRUNC, TRUNC_TIMESTAMP, DATE_FORMAT, STRFTIME, or DATEADD/DATEDIFF arithmetic where no truncation function exists. The same six levels drive the OLAP time hierarchy and its period-over-period comparisons.

SQLite rejects week and quarter buckets and says so rather than returning a quietly wrong grouping.

Capability Available on What happens elsewhere
Full-text search operators PostgreSQL, Redshift, H2 FTS, PLFTS, PHFTS and WFTS — with a validated optional language argument — are Postgres-family only. Elsewhere, use CONTAINS, LIKE, ILIKE or the regex operators MATCH and IMATCH
JSON, array and range operators PostgreSQL, Redshift Containment (@>, <@), overlap (&&), the range operators <<, >>, &<, &>, -|-, HAS_ELEMENT and the JSON-path operators are Postgres-family only
OFFSET pagination Everything except Sybase Sybase rejects OFFSET; the compiler emits TOP n instead
Week and quarter date buckets Everything except SQLite SQLite rejects both levels rather than approximating them
NULLS FIRST / NULLS LAST PostgreSQL, SQL Server, Snowflake, Redshift, BigQuery, DB2, H2 MySQL, MariaDB, SQLite and Sybase get an automatic (field IS NULL) emulation expression
ROLLUP, CUBE, GROUPING SETS PostgreSQL, BigQuery, Snowflake, Redshift, SQL Server, H2 MySQL and MariaDB get WITH ROLLUP only
Native bulk ingest for sync PostgreSQL, Redshift Native COPY with automatic fallback to batched INSERT everywhere else
Atomic staging swap PostgreSQL, MySQL, SQL Server Postgres rename, MySQL RENAME TABLE, SQL Server sp_rename. BigQuery falls back to drop, create and insert in a single transaction
CDC capture PostgreSQL, MySQL, MariaDB, SQL Server Postgres logical replication with a per-source slot and publication, MySQL and MariaDB binlog with a derived unique server id, SQL Server database-level CDC. Other engines use full reload, watermark or snapshot-delta sync
Live dashboards over push PostgreSQL LISTEN/NOTIFY on the data source re-runs the affected cards. Every other engine uses the interval strategy
Index creation in Constructions Most engines The plan preview warns where an engine has no CREATE INDEX — Snowflake, for example — before anything is executed. SQLite inlines foreign keys with a warning
Every one of these is reported at compile time or in the plan preview, not discovered when a scheduled report fails at three in the morning.
01 / AUTH

Four auth modes, credentials encrypted at rest

SQL authentication, service principal, managed identity and AAD password. Credentials are AES-encrypted in the application database, and each connection carries an extra-options JSON block for SSL settings, an SSH tunnel — host, port, user, private key and passphrase — and a BigQuery service-account key where that applies.

Because Qrly is self-hosted, the usual answer to network reachability is that it already sits inside your network. The tunnel is there for the cases where it does not.

02 / LIMITS

Execution limits, per connection

Query timeout (60 s), max rows (10,000), max stream rows (1,000,000), max concurrent queries (4), max queue size (20) and queue wait timeout (30 s) — all set per connection, so a reporting replica and a production primary can carry different rules.

The query governor enforces the last three with a semaphore sized to the concurrency limit and a FIFO wait queue, returning a queue-full error on overflow and a timeout when the wait expires. The admin page shows live per-connection stats — active, queued, max concurrent, max queue and last wait — with a recent-events table.

03 / ROLE

Source, cache target, or both

Every connection declares a role: SOURCE for reading, CACHE_TARGET for receiving materialized tables and synced tables, or BOTH. An organisation nominates a default cache-target pointer, so the materialization and table-sync tiers know where to write without being told each time.

That separation is what lets Qrly write a question's result — or a whole replicated table — into a database you own, queryable by any other tool you run.

04 / DDL

DDL enablement is per connection

A connection carries its own ddl_enabled flag, and it is the third tier of the Constructions cascade: the tenant, the organisation and the connection must each have DDL enabled, and all three default to off.

When a design is blocked, the policy service reports the outermost blocking tier, so an administrator knows which switch to look at rather than guessing down the chain.

Feature What it does
Schema sync Opt-in, default off. A manual trigger plus a nightly scheduler. It is what powers SQL autocomplete in the Monaco editor and the table and column pickers in the visual query builder
Curated metadata Override display names and descriptions on tables and columns, so cust_ord_hdr reads as "Customer orders" for everyone who did not design the schema
Data dictionary A paginated register of table, column, type, nullable, primary key, foreign key, unique, indexed, description and enum values — exportable as CSV, XLSX, PDF and Markdown, with a print view
ERD viewer A Mermaid entity-relationship diagram with relationships-only or all-tables modes, column detail set to all, keys or none, table multi-select, pointer-anchored zoom from 0.1x to 4x, pan, fit and fullscreen
Freshness probe Nominate a table and a timestamp column; a five-minute scheduler runs SELECT MAX(col) and drives the "Data as of …" badges shown on questions and dashboards
Browse endpoints Schema browse and per-table detail endpoints, so the schema is available to the API and to the AI tool layer as well as the UI
AI on the schema Describe a table, describe all tables, and a written explanation of what the connection holds, with regenerate. Per-connection aiSystemPrompt, and aiRowAccessEnabled is opt-in — schema-only by default, so no row ever reaches a model unless you say so
Schema sync reads metadata, not rows. Sending row data to an AI provider is a separate, per-connection opt-in.

How the guarantee is actually enforced

Not a convention, not a documented recommendation — four independent mechanisms, each of which would have to fail for a write to reach your source.

  1. The pool hands out read-only connections. Every connection the pool issues has setReadOnly(true) applied, so the driver itself refuses a write before any Qrly code is consulted.
  2. The SQL sanitizer. Native SQL must start with SELECT or WITH. A long keyword blocklist is rejected outright: DROP, DELETE, INSERT, UPDATE, TRUNCATE, ALTER, CREATE, GRANT, REVOKE, EXECUTE, EXEC, CALL, MERGE, REPLACE, LOAD, IMPORT, EXPORT, COPY, VACUUM, ANALYZE, LISTEN, NOTIFY, LOCK, SET, RESET, BEGIN, COMMIT, ROLLBACK, SAVEPOINT, DO, DECLARE and REFRESH. The Monaco editor mirrors the same list client-side, so the warning appears as you type rather than on run.
  3. Every parameter is bound. Native SQL {{template_variables}} and interactive filter values become prepared-statement parameters, typed from their declaration or from context — never string-interpolated. Calculated fields go through a separate expression sanitizer: no semicolons, no comments, no DDL, DML or subquery keywords, balanced parentheses and quotes, a 1,000-character cap, identifier rules and a reserved-word list.
  4. DDL only through Constructions. The single path that can change a schema is Constructions, and it is gated by a three-tier cascade — tenant, organisation and connection must each have ddl_enabled, all defaulting to off — on top of which the caller needs FULL data access on the target. Statements run one at a time in auto-commit, stopping at the first failure, and each run records the verbatim SQL, the statement count, the status, the duration and who triggered it. Even the AI assistant cannot bypass this: it proposes a design document, never SQL, which is rebuilt field by field through the DDL generator as a trust boundary.

Permissions sit above all of this: data access runs NO_ACCESSRESTRICTED (run saved questions only, cannot author SQL) → FULL (author and run any SQL — also required for RPC, table writes and applying a Construction). Every executed statement lands in the query audit log with its row count, duration, status and error, under a retention policy enforced daily.

01 / BROWSE

External tables and views

Browse the external tables and views defined in a Synapse workspace directly from the connection, alongside the ordinary schema browser. What is already published in the lake is visible without leaving Qrly.

02 / GENERATE

OPENROWSET Delta Lake view DDL

Generate OPENROWSET Delta Lake view DDL either from an existing object — pointing at what is already there — or from scratch, and preview the Delta paths before anything is created. The generated DDL is a script you review, not something applied behind your back.

03 / QUERY

Then it is just another connection

Once a view exists, Synapse behaves like any other connection: schema sync, the data dictionary, the ERD, the visual builder, QQL, OLAP models, dashboards, alerts and the Data API all work against it unchanged.

04 / GOVERN

Same governance, same audit

Read-only enforcement, per-connection execution limits, the query governor, the per-user daily query budget and the query audit log apply identically. Synapse tooling adds a surface; it does not open a side door.

How many databases does Qrly connect to?

Forty connection types. Twenty native engines — PostgreSQL, MySQL, MariaDB, SQL Server, SQLite, H2, HSQLDB, Derby, DuckDB, Snowflake, Redshift, BigQuery, ClickHouse, Vertica, Trino, Presto, SingleStore, DB2, Sybase via jTDS and Pervasive.

Plus the managed-cloud variants, each with its own type string: AWS Aurora Postgres and MySQL, RDS Postgres, MySQL, MariaDB and SQL Server, Redshift and Athena; Azure SQL, Synapse, Postgres, MySQL and MariaDB; GCP Cloud SQL Postgres, MySQL and SQL Server, AlloyDB, BigQuery and Spanner.

My engine is not listed — Oracle, MongoDB, SAP HANA?

They are not supported. Oracle, Teradata, SAP HANA, Cassandra, MongoDB, Dremio and Firebird have no driver and no dependency in the build, and CockroachDB is recognised by the dialect resolver but has no driver mapping. Older project notes list some of those engines; the shipping code does not, and we would rather say so here than after a proof of concept.

There are two workable routes. Trino and Presto are both supported and both compile as Postgres, so a federated query engine can front what Qrly cannot reach directly. Or replicate the tables you need into a supported target with table sync, and query the copy.

How does Qrly handle SQL differences between engines?

Twelve dialect compilers — POSTGRES, MYSQL, MARIADB, SQLSERVER, BIGQUERY, SNOWFLAKE, REDSHIFT, SQLITE, H2, DB2, SYBASE and PERVASIVE — cover all forty connection types, because wire-compatible engines fold into an existing dialect rather than getting a half-finished one of their own. CockroachDB, Vertica, Trino, Presto, DuckDB, ClickHouse, Athena and Spanner compile as POSTGRES; SingleStore as MYSQL; HSQLDB and Derby as H2. Unknown types default to POSTGRES.

Each dialect resolves identifier quoting, the pagination form (LIMIT/OFFSET, OFFSET…FETCH NEXT or TOP n), NULLS FIRST/LAST support with an emulation expression where the engine lacks it, and per-level date bucketing with the right function spelling. A type classifier normalises the raw JDBC type names on top, so the filter UI offers the operators that engine actually supports.

Can Qrly write to my database?

Not through the query path. The connection pool hands out read-only connections, native SQL must start with SELECT or WITH, a long keyword blocklist covering DROP, DELETE, INSERT, UPDATE, TRUNCATE, ALTER, CREATE, GRANT, REVOKE, EXEC, CALL, MERGE, COPY, SET and more is rejected outright, and every parameter is bound rather than interpolated.

DDL is only ever possible through Constructions, and only when the tenant, the organisation and the connection all have DDL enabled — three flags that each default to off — and the caller additionally holds FULL data access on the target. Materialized tables and table sync write only to a connection you have explicitly marked CACHE_TARGET or BOTH.

Does Qrly read my schema, and is that optional?

Schema sync is opt-in and defaults to off. When you enable it you can trigger it manually or leave it to the nightly scheduler; it powers SQL autocomplete and the visual query builder.

On top of the raw schema you can curate metadata — override display names and descriptions on tables and columns — browse a paginated data dictionary exportable as CSV, XLSX, PDF and Markdown, and read the relationships as a Mermaid ERD with pointer-anchored zoom from 0.1x to 4x. Sending actual row data to an AI provider is a separate per-connection opt-in; the default is schema-only.

How do I connect to a database that is not publicly reachable?

Qrly is self-hosted, so in most deployments it already sits inside the same network as the database and no tunnel is needed at all.

Where it does not, each connection carries an extra-options JSON block supporting SSL settings and an SSH tunnel with host, port, user, private key and passphrase, plus a BigQuery service-account key where that applies. Authentication modes cover SQL auth, service principal, managed identity and AAD password, every credential is AES-encrypted at rest, and the connection can be tested both before and after saving.

Page updated 28 August 2026. Connectivity reflects Qrly 1.1.695.

Point it at your database

Qrly runs on your own infrastructure, next to the data. Connect, test, sync the schema if you want autocomplete — and query read-only from the first minute.