@crvouga/mockingbird-service-postgres 3.5.0 → 3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog — @crvouga/mockingbird-service-postgres
2
2
 
3
+ ## 3.7.0 (2026-10-17)
4
+
5
+ ### Features
6
+
7
+ - resolve fleet and emulator issue batch ([26d2f8c](https://github.com/crvouga/mockingbird/commit/26d2f8cee99fefed93192204bac44fb1be35c1da))
8
+
9
+ ## 3.6.0 (2026-10-15)
10
+
11
+ ### Features
12
+
13
+ - resolve SQL, routing and writer gaps ([73f97d0](https://github.com/crvouga/mockingbird/commit/73f97d0d2379f44b9131180498f4fab76648fed9))
14
+
3
15
  ## 3.5.0 (2026-10-15)
4
16
 
5
17
  ### Features
package/COMPATIBILITY.md CHANGED
@@ -96,6 +96,9 @@ The oracle exposes **2787 builtin functions** and **74 operators** in `pg_catalo
96
96
  | `COMMENT ON INDEX`, `pg_description`, `obj_description` | VERIFIED | Stored on the index: replace, clear with `NULL` or `''`, removed with the index / table / schema, kept through renames, transactional, in snapshots, isolated per wire transaction; `42P01` / `3F000` / `42809` for a missing index, a missing schema, a relation that is not an index. Comments on every other kind of object are still accepted and not stored (divergence `comment-on-not-stored`) (`tests/contract/catalogs/index-comments.test.ts`) |
97
97
  | `regnamespace`, `to_regnamespace` | VERIFIED | Input (`-`, an all-digit oid, or exactly one identifier, case-folded unless quoted), output (quoted like `quote_ident`, numeric when no schema has the oid, `-` for zero), casts from text / name / oid / integers, implicit use as `oid` in comparisons, `pg_toast` / `pg_catalog` / `information_schema`; `3F000`, `42602` and `22003` as PostgreSQL raises them. `public` has a generated oid, not 2200 (`tests/contract/catalogs/regnamespace.test.ts`) |
98
98
  | `pg_stat_user_tables`, `pg_stat_user_indexes`, `ANALYZE` | PARTIALLY VERIFIED | PostgreSQL 18's columns and types; one row per user table and materialized view (and per index), `relid` joins `pg_class.oid`, follows create / drop / rename / schema moves, restored with snapshots. `n_live_tup` is the exact row count, immediately; `ANALYZE` validates its targets (`42P01`, `42703`, `42701`, `42601`) and records `analyze_count` / `last_analyze` from the database clock. Not tracked (read zero / NULL): scans, tuples inserted / updated / deleted, dead tuples, vacuum; `idx_scan` counts only the unique-key lookups made for `SELECT`. `VACUUM ANALYZE` does not count. Temporary tables are listed under the schema they were created in, not `pg_temp` (divergence `pg-stat-counters-immediate`) (`tests/contract/catalogs/table-statistics.test.ts`) |
99
+ | Storage-default session settings | VERIFIED | `default_tablespace` (empty/database default or `pg_default`) and `default_table_access_method` (`heap`), SHOW/current_setting/set_config/RESET and transaction-local scope. Unknown methods/tablespaces fail with `22023`. Physical storage placement is not modelled (`tests/contract/misc/storage-defaults.test.ts`) |
100
+ | Materialized view indexes | PARTIALLY VERIFIED | Ordinary/partial/unique indexes, creation before population, catalog links, unique enforcement and atomic failure on refresh, snapshot roundtrip. Physical access methods and concurrent refresh are not modelled (`tests/contract/views/materialized-indexes.test.ts`) |
101
+ | Constraint triggers | PARTIALLY VERIFIED | AFTER ROW multi-event triggers, DEFERRABLE INITIALLY DEFERRED/IMMEDIATE, final-state execution at commit, failed-commit rollback, SET CONSTRAINTS and savepoints; definitions survive snapshots, pending events cannot be exported. Uses the existing plpgsql-lite subset (`tests/contract/triggers/deferred.test.ts`, `tests/wire/deferred.test.ts`) |
99
102
  | Triggers (row-level, LANGUAGE sql-expressible) | PARTIALLY VERIFIED | Creation-order firing, `UPDATE OF` ignored, no INSTEAD OF (documented) |
100
103
  | CREATE FUNCTION LANGUAGE sql / plpgsql-lite | PARTIALLY VERIFIED | Scalar + set-returning; plpgsql subset: DECLARE, EXCEPTION WHEN others, CASE, FOR-IN-SELECT, RETURN NEXT |
101
104
  | Text search (tsvector / tsquery / @@ / ts_rank) | PARTIALLY VERIFIED | `simple`-style config; no ispell/synonym dictionaries |
@@ -138,3 +141,34 @@ PostgreSQL; clock profiles are supported. This adds fleet orchestration around e
138
141
  snapshot semantics, not a broader SQL compatibility claim. Acceptance evidence is
139
142
  `packages/adapters/node/fleet.management.test.ts` using the unmodified `pg` wire client.
140
143
  See [Fleets](../../../docs/FLEETS.md).
144
+
145
+ ## Schema preflight and row-version metadata
146
+
147
+ `analyzeSchema(sql, options)` (the package's main export) checks plain schema SQL in a discarded
148
+ in-memory database and returns a JSON-serializable report, including the installed build version,
149
+ statement offsets/lines/columns, object names, SQLSTATEs, independent failures and identifiable
150
+ missing prerequisites. Defaults cap input at 1 MiB, statements at 1,000 and diagnostics at 100;
151
+ configurable hard caps are 4 MiB, 10,000 and 1,000. It does not execute data statements, contact an
152
+ oracle or change an existing database. Accepted statements remain explicitly **unknown** for full
153
+ semantic compatibility, including deferred SQL/PL/pgSQL bodies and dynamic SQL. A detected gap sets
154
+ `compatible: false`; otherwise it stays `null`, never a claim of a verified import. Source-tree
155
+ execution identifies the version as `source-tree`; published builds embed their package version.
156
+ Lexical errors that prevent reliable statement recovery terminate the scan.
157
+
158
+ SQL and PL/pgSQL function definitions retain comma-separated `SET` lists (including `search_path`),
159
+ apply them during calls and restore the caller's settings on return or error. Portable snapshots
160
+ retain these settings. Sequence functions accept explicit `regclass` input, and
161
+ `pg_get_serial_sequence` finds owned serial, identity and explicitly owned sequences using exact
162
+ column-name case; ownership follows sequence/table/column renames and snapshots.
163
+
164
+ Stored tables expose `xmin` and `alias.xmin` as hidden `xid` system columns. INSERT, UPDATE, upsert,
165
+ COPY and referential-action writes stamp row versions with a local transaction identity; explicit
166
+ transactions share that identity, including wire workspace replay and commit. Rollback restores
167
+ committed row metadata. Snapshots preserve identities and continue allocation above retained IDs;
168
+ legacy PGMM snapshots without metadata expose frozen xid `2`. Each database/namespace owns its
169
+ allocator. These identities are version markers, not permanent globally unique row identifiers.
170
+ The implementation does not add full MVCC, VACUUM/freeze maintenance, physical tuple metadata or
171
+ xid wraparound management; it fails when the 32-bit allocation space is exhausted.
172
+
173
+ Evidence: `tests/contract/regressions/issue-queue.test.ts` (PostgreSQL 18.3 differential contracts),
174
+ `tests/contract/api/schema-report.test.ts`, and `tests/wire/issue-queue.test.ts`.
package/README.md CHANGED
@@ -529,6 +529,11 @@ search, `ON CONFLICT DO NOTHING/UPDATE`, `RETURNING`, `PREPARE`/`EXECUTE`/`DEALL
529
529
 
530
530
  ## API
531
531
 
532
+ `analyzeSchema(sql, options?)` returns bounded, JSON-serializable schema compatibility diagnostics
533
+ without changing an application database. Accepted statements remain semantically unverified;
534
+ see [schema preflight and row-version metadata](COMPATIBILITY.md#schema-preflight-and-row-version-metadata)
535
+ for limits, the report contract and `xmin` support.
536
+
532
537
  Stable runtime exports of the main entry:
533
538
 
534
539
  | Export | Description |
@@ -4,6 +4,8 @@ const D = "documented_divergence" as const;
4
4
  const REPORT = ["tests/contract/_reports/session-system.md"];
5
5
 
6
6
  export const TRG_SECTION: CatalogSection = section("TRG", "Triggers", true, [
7
+ ["deferred-01", "deferred constraint trigger observes final transaction state"],
8
+ ["deferred-02", "SET CONSTRAINTS IMMEDIATE flushes pending events"],
7
9
  ["bi-01", "BEFORE INSERT trigger assigns a NEW column"],
8
10
  ["bi-02", "BEFORE INSERT trigger computes from another NEW column"],
9
11
  ["bi-03", "BEFORE INSERT returning NULL suppresses the row"],