Module pgwire

Module pgwire 

Source
Expand description

The PostgreSQL wire protocol, served over a program’s read models.

docs/05-tier-lowering.md §5.3 asks for “pgwire access for the outside world: psql, BI tools, DBeaver see materialized views as ordinary tables — the single cheapest trust-builder for adopting teams”, and 07 §7.2 files it under external-tool compatibility with no alternative listed. [beck_core::read] is what the tables are; this is the socket.

§Why it is written here rather than taken

There are crates that implement this protocol server-side. What they carry is the rest of a database — a type registry, an extended-protocol state machine over prepared statements with parameters, portals that suspend — and a read model has none of those to expose. What is actually needed is the startup exchange, the simple query, the extended query with no parameters, and four type OIDs a driver already knows. That is this file, and it adds no dependency to a workspace whose §7.9 pins everything (adr/0020).

§What it deliberately does not do

  • No authentication. It answers AuthenticationOk to everyone, which is why serve refuses to bind anywhere but the loopback interface. An unauthenticated read of an application’s whole state must not be reachable from another host, and a flag that turns that off is a decision with an ADR rather than a convenience.
  • No TLS. The same reason and the same bound.
  • No writes. The log is the only way state changes; a read model that accepted an insert would be a second way, which is the property 01 §1.1 is about.

§pg_catalog, and why it is not here either

psql’s \d sends a join against four catalogue relations, and those relations are read models: [beck_core::pg] derives pg_class, pg_namespace, pg_attribute and the rest from the same [Schema] this file serves, and they are scanned, filtered and joined by the operators every other query goes through. Nothing in this file knows what a backslash command is. A catalogue answered by matching the query text would be a second query path — one that could drift from the schema, and one no select could reach — where this one cannot disagree with the schema because it is the schema under another set of column names.

\d, \d <table>, \dt, \dn and \l are what that answers. Anything else asks for an object a read model does not have — a function, a role, an index — and is refused by the name of the relation it asked for ([beck_core::pg::Rel::missing]) rather than by an empty answer. [beck_core::read::Schema::CATALOGUE] is still the table that says what a read model is derived from, which is the question pg_catalog has no column for.

Functions§

bind
Bind the read-model port, refusing anything but loopback.
serve
Serve a program’s read models on the PostgreSQL wire protocol.
serve_on
Serve on an already-bound listener.