feat(datastore): add the maven_virtual_repository_upstreams schema (S30 plan: 2/25)
Adds the junction carrying a Maven virtual repository's ordered upstream list: parent plus 64 HASH(namespace_id) partitions, the DEFERRABLE INITIALLY DEFERRED position constraint, the duplicate-upstream unique index, the reverse (namespace_id, upstream_repository_id) index, and the two opposite-action foreign keys. Shape copied from the container junction, so the keys land as trailing ALTER TABLE ... ADD CONSTRAINT statements. The Up path runs unbounded per issue 548 and Step 1; only the Down sets lock_timeout and statement_timeout, with the RESET bracket around it.
Tests are one integration file: four behavioral tests plus the two static shape checks. The behavioral four are the reorder that commits in one transaction and fails as two statements, the association rows the table refuses plus both inclusive position ends and the absent-target refusals, the ON CONFLICT refusal the deferred key raises, and the two opposite delete actions. TestMavenVirtualUpstreamsSchema_MigrationShape and _DownLockBudget pin what the dump cannot see: the -- +goose NO TRANSACTION directive, the trailing ALTER TABLE placement of each key, one DROP per statement with no batching DO $$ block, and the Down SET/RESET timeout bracket. Catalog assertions (columns, index names, foreign key actions) are left to structure.sql, which the dump-structure check pins byte-for-byte. The plan's two-file npm mirror and its enumerated kind/format/visibility sweep are not carried; !2727 amends the plan to record Step 2 as one file.
No e2e catalog change and no docs/user change: the table is reachable only by direct SQL until the management API and the virtual resolver land, so no client-visible behavior moves.
Reviewable diff is about 783 lines and stays in one MR: 385 of them are the migration, and the 64 partition creates plus their 64 drops are most of that, mechanical and read as one block. The rest is the 382-line test file, 3 lines across two existing test files and 13 lines of docs. structure.sql and internal/datastore/jet/** are generated. Splitting the partition list off the table it partitions would leave two halves that only make sense together.
Related to #289
Database Review Evidence
Migrations
Note
Timings are from CI (db:migrate matrix, goose verbose) against an
empty database, in apply / rollback order per PG version.
Production-scale validation via Database Lab is not yet available. See
Database review evidence
for the matrix rationale and how to read the numbers.
| Migration | PG 16 | PG 17 | PG 18 |
|---|---|---|---|
20260916101800_create_maven_virtual_repository_upstreams.sql |
OK (1.65s / 427.89ms) | OK (527.8ms / 177.05ms) | OK (1.72s / 491.41ms) |
Migration notes:
create_maven_virtual_repository_upstreams.sql: apply is over 1.5s on PG 16 and PG 18. The time is 64 partition creates plus three indexes and three foreign keys on empty tables, catalog writes with no row scan, so production runtime matches CI and sits far inside the 5-minute boot budget. Same shape and range as Step 1's table (!2697 (merged): 0.5s to 1.06s).