Status: Accepted (2026-07-22)
corium-sql (ADR-0011) executes read-only SQL locally against an immutable
corium_db::Db value, and the corium sql shell exposes it interactively.
That shell is Corium-specific: it requires the corium binary and speaks a
bespoke REPL. A large ecosystem of tools — psql, JDBC/ODBC drivers,
psycopg, pgx, and BI front ends — instead speaks the PostgreSQL v3 wire
protocol. Exposing the existing SQL projection over that protocol makes those
tools work against Corium without a new client library, while keeping the
storage model and query location unchanged.
A new crate, corium-pgwire, implements the PostgreSQL v3 frontend/backend
protocol and answers every query by running it through a corium_sql::SqlSession
built from a Db value obtained from a DbCatalog. The read-only guarantee is
inherited rather than re-implemented: SqlSession already rejects DDL, DML,
and session-mutating statements, so the wire server adds no write path.
One server exposes the transactor's whole catalog rather than a single
database. DbCatalog is an async trait — list() enumerates the databases and
db(name) returns a fresh immutable snapshot — that implementations back with
lazily opened, cached peer connections, so a database and its segment cache are
shared across all client connections that use it. A connection selects its
database with the standard startup database parameter and switches with
USE <database>; SHOW DATABASES lists the catalog. The database is validated
lazily on first use, so a client may connect with an unknown conventional
default and then USE a real one. The CLI can restrict the exposed set with a
whitelist.
Scope of the first implementation:
Query, including
multiple semicolon-separated statements) and the extended protocol
(Parse/Bind/Describe/Execute/Sync/Close/Flush) for statements
without bound parameters, so drivers that always prepare paramless queries
work.feature_not_supported errors rather than silently mishandled. Substituting
bind parameters into SQL text safely is deferred; the immutable model makes
read-only parameterization a pure future optimization, not a correctness gap.BEGIN, COMMIT, ROLLBACK,
SET, RESET, and DISCARD are accepted as no-ops. Each query already sees
one immutable snapshot, so an explicit transaction block spans nothing the
server can violate, and accepting these lets standard clients and pools
connect cleanly.pg_type OIDs. Corium's SqlValue/SqlType map to
PostgreSQL types: integers to int2/int4/int8, 64-bit unsigned entity
ids to numeric (lossless in text), floats to float4/float8, instants to
timestamptz in UTC, bytes to hex bytea, and cardinality-many lists to the
matching array type.The crate depends only on corium-sql, corium-db, corium-core, tokio,
and async-trait; it does not depend on corium-peer, so the catalog is a
trait. The corium postgres-server CLI command supplies a PeerCatalog that
lists databases through the transactor's admin API and opens each one as a
cached peer Connection on first use.
SqlSession, so SQL semantics stay defined in one place.pg_catalog are not served.Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |