feat(oci): add container virtual upstream schema (S32 plan: 2/19)

What this does

Creates container_virtual_repository_upstreams, the ordered association table between a container virtual repository and its hosted or remote upstream repositories.

The migration adds 64 hash partitions, a UUIDv7 identifier check, three foreign keys, the deferrable unique constraint for atomic position swaps, the unique upstream association constraint, and the reverse lookup index. The schema suite verifies the catalog shape, each constraint, all delete actions, and transactional reordering.

Decisions a reviewer should check first

  • The constraint on (namespace_id, container_virtual_repository_id, position) is DEFERRABLE INITIALLY DEFERRED. Two associations can exchange positions with two UPDATEs in one transaction. The same swap fails in autocommit mode.
  • position is one-based. position = 0 and negative values fail the position >= 1 check.
  • The virtual-repository foreign key cascades. The upstream repository foreign key uses NO ACTION, so a listed upstream cannot disappear without an explicit association change.
  • The migration sets five-second lock and statement timeouts before the schema changes. Its Down section sets the same timeouts before all drops.

Spec coverage

Spec: docs/specs/S32-container-virtual.md

Criterion Tests
A listed upstream delete is refused and its association remains. TestContainerVirtualUpstreamsConstraints_DeleteActions/listed_upstream_is_refused
Deleting a virtual repository removes its associations. TestContainerVirtualUpstreamsConstraints_DeleteActions/virtual_repository_cascades
The upstream foreign key rejects a cross-namespace repository. TestContainerVirtualUpstreamsConstraints_RejectsInvalidAssociations/cross_namespace_upstream
One upstream cannot occur twice in one virtual repository list. TestContainerVirtualUpstreamsConstraints_RejectsInvalidAssociations/duplicate_upstream
Two updates reorder positions in one transaction, and an autocommit half-swap fails. TestContainerVirtualUpstreamsConstraints_ReorderAndRejectsAutocommit
Positions below one are rejected. TestContainerVirtualUpstreamsConstraints_RejectsInvalidAssociations/position_zero, position_negative
The parent has 64 hash partitions, its keys and indexes propagate to leaves, and its columns have the required shape. TestContainerVirtualUpstreamsSchema_PartitionedTableAndColumns, KeysAndIndexes, PositionUniqueIsDeferredOnEveryLeaf
The migration has safe Up and Down structure. TestContainerVirtualUpstreamsSchema_DeferrableMigrationShape

Amendment URLs the step books

None. The ADR-007 amendment is not a prerequisite for this step.

Size

This MR has 755 reviewable lines: 389 lines of migration DDL, 358 lines of integration tests, and 8 changed test lines. The migration, generated schema, Jet output, and its schema suite form one atomic unit. Splitting them would leave an unverified schema or stale generated output.

The regenerated structure.sql and Jet files add 2,125 generated lines. The full diff is 2,866 added lines and one removed line.

Checks

  • ARTIFACT_REGISTRY_DATABASE_TEST_DSN='postgres://ar:pw@127.0.0.1:15433/ar?sslmode=disable' mise exec -- go test -tags=integration ./internal/datastore/migrations -count=1
  • The pre-commit hook passed for test(migrations): fix upstream schema static assertions.

No e2e scenario is added or affected. This schema step creates no request path. S32 Step 18 owns the end-to-end harness and catalog entries.

Sibling overlap

  • !2267 (merged) overlaps on internal/datastore/migrations/structure.sql and internal/datastore/migrations/migrations_checksum_test.go.
  • !1011 (closed) overlaps on internal/datastore/migrations/structure.sql, internal/datastore/migrations/migrations_checksum_test.go, and internal/datastore/jet/artifact_registry/public/table/table_use_schema.go.

Both overlaps are regenerated artifacts. Rebase and regenerate after either MR merges first.

Related to #291

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
20260902100000_create_container_virtual_repository_upstreams.sql OK (1.63s / 407.38ms) OK (999.28ms / 371.04ms) OK (648.44ms / 205.62ms)

Upstream validation

The foreign key enforces namespace membership only. S17 rejects a virtual upstream and an upstream outside the container format family at association time. The read path independently rejects a direct-SQL row whose upstream kind or format is invalid, so it cannot resolve through an unsupported repository.

Edited by Radamanthus Batnag

Merge request reports

Loading
Loading