@crvouga/mockingbird-service-postgres 1.5.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -13,12 +13,11 @@ Guidance for humans and coding agents editing this repository. For install and c
13
13
  3. Single-session **engine**: no MVCC across connections, no aborted-transaction (`25P02`) state in the sync API
14
14
  4. `NOT APPLICABLE` items: roles/auth enforcement, replication, VACUUM internals, storage params, full PL/pgSQL
15
15
 
16
- **Non-goals:** matching `pg`/`postgres.js` **client APIs**, full PL/pgSQL, or MVCC. The optional
17
- wire-protocol server (`src/wire/`, a Node/Bun-only entry over the one engine) is in scope: it
18
- speaks frontend/backend v3 and coordinates connections by serializing transaction blocks, adding
19
- advisory locks, `LISTEN`/`NOTIFY`, `CancelRequest` and per-connection `25P02`. It deliberately does
20
- **not** add row-level lock contention (`SELECT … FOR UPDATE SKIP LOCKED` distribution) or `COPY`
21
- streaming.
16
+ **Non-goals:** matching `pg`/`postgres.js` **client APIs**, full PL/pgSQL, or MVCC in the synchronous
17
+ API. The optional wire-protocol server (`src/wire/`, a Node/Bun-only entry over the one engine) is
18
+ in scope: it coordinates per-session `READ COMMITTED` workspaces and adds row locks (`FOR UPDATE`,
19
+ `NOWAIT`, `SKIP LOCKED`, deadlock detection), advisory locks, `LISTEN`/`NOTIFY`, `CancelRequest`
20
+ and per-connection `25P02`. `COPY` streaming remains an explicitly documented boundary.
22
21
 
23
22
  ## SQL pipeline
24
23
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog — @crvouga/mockingbird-service-postgres
2
2
 
3
+ ## 1.7.0 (2026-10-02)
4
+
5
+ ### Features
6
+
7
+ - coordinate HTTP and protocol mocks ([3168653](https://github.com/crvouga/mockingbird/commit/31686534c55a9823fdaa92afc9cc456cf741b809))
8
+
9
+ ### Fixes and improvements
10
+
11
+ - decouple smoke types from built packages ([a4b31c6](https://github.com/crvouga/mockingbird/commit/a4b31c6205d92aa0c6f7c9de3518d5ae44d38829))
12
+ - protect child admin endpoints ([5410b94](https://github.com/crvouga/mockingbird/commit/5410b948a30dcedc21e9a70e44fd415c1ea25394))
13
+ - explain discovery and controls ([dd0fed6](https://github.com/crvouga/mockingbird/commit/dd0fed6f5f94cac51ae71f2d2e7d58a6b01ccc63))
14
+ - harden protocol startup and state ([6f5b557](https://github.com/crvouga/mockingbird/commit/6f5b557e87b48b31985949e04f3b5ef58f51d295))
15
+ - preserve checkpoints and lifecycle ([50e8c32](https://github.com/crvouga/mockingbird/commit/50e8c322feded2f7f45afce9d8cdef43c37ab9ab))
16
+ - clean branch state on reset ([3b714d4](https://github.com/crvouga/mockingbird/commit/3b714d4a5df8e75fee0bb31e98d7c7566e164381))
17
+ - type signal listener cleanup ([5279852](https://github.com/crvouga/mockingbird/commit/5279852e56ea60262ccf17aa6e46b3c31091a34a))
18
+
19
+ ## 1.6.0 (2026-10-01)
20
+
21
+ ### Features
22
+
23
+ - add MVCC row locks ([9e199e0](https://github.com/crvouga/mockingbird/commit/9e199e083c3d16a9a2acfd7a2e9ab00ad733ef4f))
24
+ - stream COPY protocol ([9e7a867](https://github.com/crvouga/mockingbird/commit/9e7a8673206fd6dad1b170e1b3a31e183e5abb2f))
25
+ - add database catalogs ([c9b2c06](https://github.com/crvouga/mockingbird/commit/c9b2c060af4919135926c805412886177b4026a0))
26
+ - parse identity sequence names ([e7a5a03](https://github.com/crvouga/mockingbird/commit/e7a5a03f33e6d5a0dc28a34d30659bb128db7c73))
27
+ - accept tooling session GUCs ([0464416](https://github.com/crvouga/mockingbird/commit/04644162f7bbd5071e580cfb398b3da82a2a4952))
28
+
3
29
  ## 1.5.1 (2026-10-01)
4
30
 
5
31
  ### Fixes and improvements
@@ -26,6 +52,7 @@
26
52
  - allow unpopulated materialized views to reference each other ([3ce1d8f](https://github.com/crvouga/mockingbird/commit/3ce1d8f555ed4008dd894aed20ebf64ab0253774))
27
53
  - support CREATE EXTENSION pg_trgm ([2296ba2](https://github.com/crvouga/mockingbird/commit/2296ba2f3d1a9ea7ce8ec9f528e979034692ebf1))
28
54
  - install pgcrypto digest() ([b5f3ccf](https://github.com/crvouga/mockingbird/commit/b5f3ccf79c6fedcabab157f1ee07af18a7871057))
55
+ - boot Bolt over Socket Mode ([01322df](https://github.com/crvouga/mockingbird/commit/01322df315c66b1f2f5b53094cbbeeeef6d3ae6c))
29
56
 
30
57
  ## 1.3.1 (2026-09-29)
31
58
 
package/COMPATIBILITY.md CHANGED
@@ -10,13 +10,21 @@ See [COMPATIBILITY-AUDIT.md](COMPATIBILITY-AUDIT.md) for the latest evidence-bas
10
10
 
11
11
  Reference oracle: **PostgreSQL 18.3** via PGlite (`@electric-sql/pglite`, real Postgres compiled to WASM, in-process). Inventory: `bun run inventory`. Construct catalog: `bun run scenarios` → [`compat/scenarios.ts`](compat/scenarios.ts). Divergences: [`compat/divergences.json`](compat/divergences.json). Requirements matrix: `bun run requirements` → `compat/requirements.json` + `compat/coverage.json`.
12
12
 
13
+ The Node `/server` entry participates in protocol fleets. Acceptance tests use `pg@8.23.0`
14
+ for authenticated readiness, shutdown, namespace isolation, full-catalog reset/snapshot/restore and
15
+ clock controls. This supervisor surface does not change the SQL dialect compatibility contract.
16
+
13
17
  ## Proof surface
14
18
 
15
19
  Differential tests compare a **tuple** per statement: rows (normalized to canonical PostgreSQL text where typed), column names and type names where requested, error SQLSTATE class + normalized message, command tag / `rowCount`, and transaction status, plus a **logical state dump** (catalog names, column definitions, row payloads, sequence values) after write sequences.
16
20
 
17
21
  A catalog ID appearing in a test file is **not** proof by itself. Trivial probes are tracked in [`compat/smoke-baseline.json`](compat/smoke-baseline.json) and ratcheted downward (currently **0 smoke stubs** across 945 catalog scenarios). Generated operator/cast matrices live under [`tests/contract/matrices/`](tests/contract/matrices/). Observed mem≠oracle diffs must bind to a `compat/divergences.json` entry or be a **FAILURE** — unexplained diffs are not allowed.
18
22
 
19
- Intentional differences are finite and machine-readable in `compat/divergences.json` (PGMM snapshots, seeded `random()`/`now()`, sync single-session API, no aborted-transaction state, EXPLAIN stubs, trigger-order/`UPDATE OF` edges, float8 rounding/overflow edges, …). Human-readable: [DIVERGENCES.md](DIVERGENCES.md).
23
+ Intentional differences are finite and machine-readable in `compat/divergences.json` (PGMM snapshots, seeded `random()`/`now()`, sync single-session API, no aborted-transaction state, EXPLAIN stubs, trigger-order/`UPDATE OF` edges, float8 rounding/overflow edges, …). The wire server supports isolated database catalogs, startup selection, database lifecycle DDL, and copy-on-write template cloning. Human-readable: [DIVERGENCES.md](DIVERGENCES.md).
24
+
25
+ The wire server supports protocol-v3 text and CSV `COPY FROM STDIN` / `COPY TO STDOUT`, including
26
+ incremental `CopyData`, client aborts, and statement-atomic rollback. Binary COPY remains outside
27
+ the compatibility surface.
20
28
 
21
29
  ## Status vocabulary
22
30
 
@@ -33,7 +41,7 @@ Anything a PostgreSQL application can invoke through SQL against the PGlite **18
33
41
 
34
42
  1. **Snapshot format** — custom binary codec (`PGMM`), not `pg_dump` / on-disk clusters (logical state still round-trips).
35
43
  2. **Deterministic `random()` / `now()`** — seeded PRNG and fixed clock by default (injectable).
36
- 3. **Single session** — no MVCC across connections, no isolation levels beyond one session, no `25P02` aborted-transaction state (documented divergence).
44
+ 3. **Single-session sync API** — no concurrent sessions or `25P02` aborted-transaction state. The optional wire server separately provides per-session `READ COMMITTED` workspaces and row locks.
37
45
  4. **NOT APPLICABLE** rows in `compat/coverage.json` (roles, replication, VACUUM internals, LISTEN/NOTIFY, cursors, full PL/pgSQL, extensions other than `pgcrypto`'s `digest()` and `pg_trgm`'s `similarity` / `<%` / `gin_trgm_ops`).
38
46
 
39
47
  The oracle exposes **2787 builtin functions** and **74 operators** in `pg_catalog`; postgres-mem implements **302 functions** and **41 operators**, and every remaining item is an explicit entry in [`compat/unsupported-register.json`](compat/unsupported-register.json) with a reason (trigger/internal plumbing, admin/monitoring, unsupported type families, …). The gate fails closed on silence.
@@ -56,7 +64,7 @@ The oracle exposes **2787 builtin functions** and **74 operators** in `pg_catalo
56
64
  | GROUPING SETS / ROLLUP / CUBE, DISTINCT ON, LATERAL, set ops | VERIFIED | |
57
65
  | Recursive + data-modifying CTEs | VERIFIED | |
58
66
  | Constraints: PK / UNIQUE / NOT NULL / CHECK / FK actions | VERIFIED | DEFERRABLE parsed, checked at statement end |
59
- | Sequences / serial / identity | VERIFIED | |
67
+ | Sequences / serial / identity | VERIFIED | Includes pg_dump identity sequence names and options |
60
68
  | Schemas + search_path + pg_catalog / information_schema | VERIFIED | Catalog columns are the commonly-queried subset |
61
69
  | Enums, domains, generated columns | VERIFIED | |
62
70
  | Triggers (row-level, LANGUAGE sql-expressible) | PARTIALLY VERIFIED | Creation-order firing, `UPDATE OF` ignored, no INSTEAD OF (documented) |
@@ -65,14 +73,15 @@ The oracle exposes **2787 builtin functions** and **74 operators** in `pg_catalo
65
73
  | `CREATE EXTENSION pgcrypto` / `digest()` | PARTIALLY VERIFIED | `digest(bytea, text)` and `digest(text, text)` for md5, sha1, sha224, sha256, sha384, sha512. `crypt`, `hmac`, `gen_salt`, and PGP functions are not installed. OpenSSL-only names (sha3, blake2, ripemd160, sm3) are not available. Extensions other than `pgcrypto` and `pg_trgm` still fail loud (`0A000`) |
66
74
  | `CREATE EXTENSION pg_trgm` | PARTIALLY VERIFIED | `similarity(text, text)`, `<%` at the default word-similarity threshold 0.6, and a single-column `gin_trgm_ops` index on `text` or `varchar`. `gist_trgm_ops`, multicolumn `gin_trgm_ops`, and non-default thresholds are not installed. |
67
75
  | COPY FROM/TO (text, csv) | VERIFIED | Via `copyFrom` API hook / rows out |
68
- | PREPARE / EXECUTE / DEALLOCATE, SET / SHOW / RESET | VERIFIED | GUC subset |
76
+ | PREPARE / EXECUTE / DEALLOCATE, SET / SHOW / RESET | VERIFIED | GUC subset, including PostgreSQL dump and migration-client preambles |
69
77
  | Transactions / savepoints | VERIFIED | No `25P02` aborted state (documented divergence) |
70
78
  | Collation / ordering | PARTIALLY VERIFIED | `C` semantics pinned; locale/ICU out of scope |
71
79
  | Regex (`~`, `~*`, POSIX functions) | PARTIALLY VERIFIED | JS regex flavor mapped to POSIX ERE; documented edges |
72
80
  | EXPLAIN | PARTIALLY VERIFIED | Stub plan shapes |
73
81
  | MERGE / CALL / cursors / LISTEN / full PL/pgSQL | UNSUPPORTED | Fail loud `0A000`, registered |
74
82
  | Roles / GRANT / VACUUM / ANALYZE / LOCK | NOT APPLICABLE | Parsed no-ops where harmless |
75
- | Wire protocol / multi-session MVCC / on-disk format | NOT APPLICABLE | |
83
+ | Wire protocol / multi-session concurrency | PARTIALLY VERIFIED | `READ COMMITTED` workspaces; `FOR UPDATE`, `NOWAIT`, `SKIP LOCKED`, and deadlock detection |
84
+ | On-disk PostgreSQL format | NOT APPLICABLE | PGMM snapshots are the persistence format |
76
85
 
77
86
  ## How to verify
78
87
 
package/README.md CHANGED
@@ -173,6 +173,13 @@ const fromUri = await serve("postgres://postgres:secret@127.0.0.1:0/app")
173
173
  await fromUri.close()
174
174
  ```
175
175
 
176
+ The wire server owns a PostgreSQL-style database catalog. Start on `postgres`, then use ordinary
177
+ `CREATE DATABASE`, `DROP DATABASE`, and `ALTER DATABASE … RENAME TO` statements; startup packets
178
+ select an isolated engine and unknown names fail with `3D000`. `CREATE DATABASE child TEMPLATE
179
+ seed` forks `seed` through the same copy-on-write snapshot path as `Snapshot.open()`. The live names
180
+ are available through `pg_database` and `server.databaseNames()`, while
181
+ `server.getDatabase(name)` and `server.snapshot(name)` provide programmatic test controls.
182
+
176
183
  Or from the command line (installs a `mockingbird-postgres` bin):
177
184
 
178
185
  ```bash
@@ -186,15 +193,23 @@ server from one frozen template, so a seeded stack starts from the same bytes ea
186
193
  surface as every other mock, including the table explorer (`GET /sql/tables`, `POST /sql/query`).
187
194
  The wire server does not speak that HTTP API.
188
195
 
196
+ `mockingbird-postgres serve --config mockingbird.json` also supervises a mixed HTTP/Postgres/Redis
197
+ fleet through the Node `/server` entry. See [fleet configuration and controls](../../../docs/FLEETS.md)
198
+ for ephemeral discovery, namespace endpoints, aggregate health, snapshots and clocks. Each declared
199
+ namespace has an independent cluster. Fleet checkpoints restore its entire catalog, including created
200
+ and dropped databases, records, deterministic random state, faults and time; live client sessions
201
+ return a conflict until closed.
202
+
189
203
  `server.snapshot()` freezes the live state; `server.fault({ dropConnection | delayStatementMs |
190
204
  failCommit })` arms the next statement or connection for a drop, a delay, or a `40001` commit
191
205
  failure.
192
206
 
193
- One engine is shared by every connection. The engine runs one statement at a time, so a connection
194
- inside an explicit `BEGIN` block holds it until `COMMIT`/`ROLLBACK` and other connections queue
195
- behind it — which keeps read-committed visibility (an uncommitted row is never seen by another
196
- connection) by serializing transaction blocks rather than by MVCC. Across connections the server
197
- adds what a single engine does not: per-session advisory locks (`pg_advisory_lock` /
207
+ One committed engine is shared by every connection. Explicit transactions execute in per-session
208
+ copy-on-write workspaces that rebase each statement on the latest committed state, providing
209
+ `READ COMMITTED` visibility without holding an engine-wide transaction turn. Successful writes
210
+ are applied atomically at commit; rollback discards the workspace. Across connections the server
211
+ adds row locks for `SELECT … FOR UPDATE` (including blocking, `NOWAIT`, `SKIP LOCKED`, and
212
+ deadlock SQLSTATE `40P01`) and per-session advisory locks (`pg_advisory_lock` /
198
213
  `pg_try_advisory_lock` / `_xact_` / `_unlock`) with in-order waiters and deadlock detection
199
214
  (`40P01`), `LISTEN`/`NOTIFY` delivered to idle listeners, `CancelRequest` (a blocked statement ends
200
215
  `57014` and the session stays usable), and per-connection aborted-transaction state (a failed
@@ -202,13 +217,15 @@ statement in a block is `25P02` until `ROLLBACK`, with `ReadyForQuery` reporting
202
217
  SCRAM-SHA-256 and trust auth, the extended query protocol (`Parse`/`Bind`/`Describe`/`Execute`/
203
218
  `Sync`) with text and binary parameters and results, real type OIDs in `RowDescription`, and
204
219
  `23505`/`23502` errors carrying the constraint, table and column the engine names, all work over
205
- the wire.
220
+ the wire. `COPY … FROM STDIN` and `COPY … TO STDOUT` use protocol-v3 `CopyInResponse`,
221
+ `CopyOutResponse`, `CopyData`, `CopyDone`, and `CopyFail` messages. Text and CSV streams are parsed
222
+ incrementally across arbitrary frame and quoted-record boundaries; failed imports are atomic and
223
+ leave the connection in PostgreSQL's transaction state.
206
224
 
207
- **Not modelled by the server:** row-level lock contention, so `SELECT … FOR UPDATE SKIP LOCKED`
208
- parses and returns rows but does not distribute disjoint rows across concurrent workers (there are
209
- no row locks); `COPY` streaming (`CopyInResponse`/`CopyData`) — use `copyFrom` on a shared
210
- `Database`; and the binary parameter formats beyond the common scalar types (a client that sends
211
- another binary type gets `0A000`, and can switch that parameter to text).
225
+ **Not modelled by the server:** transaction ID and snapshot-inspection functions, predicate and
226
+ table locks, isolation levels beyond `READ COMMITTED`, and the binary parameter formats beyond the
227
+ common scalar types (a client that sends another binary type gets `0A000`, and can switch that
228
+ parameter to text). Binary `COPY` is not supported.
212
229
 
213
230
  ### Method semantics
214
231
 
@@ -308,8 +325,8 @@ Goal: **SQL dialect** behavioural parity vs PostgreSQL **18.3** for the sync API
308
325
  [DROP-IN-CONTRACT.md](https://github.com/crvouga/mockingbird/blob/main/packages/service/postgres/docs/DROP-IN-CONTRACT.md).
309
326
 
310
327
  The in-process API has no async client, no connection pooling and no `pg_dump` codec; the optional
311
- [wire-protocol server](#wire-protocol-server-separate-processes) adds a TCP listener and coordinates
312
- several connections over the one engine, but by serializing transaction blocks, not by MVCC.
328
+ [wire-protocol server](#wire-protocol-server-separate-processes) adds a TCP listener, per-session
329
+ `READ COMMITTED` transaction workspaces, and row-level worker locks.
313
330
  Intentional differences: custom `PGMM` snapshots; seeded `random()` / fixed `now()` by default
314
331
  (`{ random: "os" }` / `{ now: "system" }` match PostgreSQL entropy and wall clock).
315
332