Partitioned-migration Down sections are not replayable: drop the redundant DETACH PARTITION statements

Problem

docs/dev/database-migrations.md requires IF NOT EXISTS / IF EXISTS on every statement of a -- +goose NO TRANSACTION migration, so an interrupted run can be re-run. Every partitioned-table migration's Down section violates this in the same way:

ALTER TABLE IF EXISTS <parent> DETACH PARTITION partitions.<table>_pNN;
DROP TABLE IF EXISTS partitions.<table>_pNN;

The IF EXISTS guards the parent, not the child. Once the child is gone, replaying the DETACH fails.

Evidence

Verified on PostgreSQL 17 against the real migrated schema:

  • Replaying a Down after the child is already dropped fails with ERROR: relation "partitions.maven_remote_versions_p63" does not exist.
  • DROP TABLE IF EXISTS partitions.<table>_p63 on its own already removes the partition from the hierarchy (pg_inherits goes 64 → 63) and replays as a NOTICE no-op.

So the DETACH is redundant, and it is the sole source of the non-replayability. It also doubles the parent AccessExclusive acquisitions: 129 statements per Down instead of 65.

Scope

This is a family-wide convention, not a property of one migration, which is why it was not fixed in the MR that surfaced it.

  • 22 migrations, 64 DETACH statements each — 1408 statements total.
  • The shared helper assertDownDropsEveryPartitionAndParent (internal/datastore/migrations/schema_helpers_test.go) actively asserts exactly 64 DETACHes plus a per-partition by-name DETACH check, so it must change in the same MR or every format's schema suite fails.

Affected migrations: the 6 oci_container_*, 6 npm_*, 4 maven_*, 3 npm_remote_*, and 3 maven_remote_* partitioned-table creates.

Proposed change

  1. Drop the 64 DETACH PARTITION statements from each Down section, relying on DROP TABLE IF EXISTS partitions.<table>_pNN.
  2. Update assertDownDropsEveryPartitionAndParent to stop requiring them, keeping the parent-drop and per-partition-drop assertions (which are what actually guarantee no residue).

Current mitigation

No production caller reverts a migration, and Runner.Check keeps returning ErrMigrationsPending so readiness never flips on a partially-applied state — the hazard is confined to local and CI rollback paths. That is policy rather than mechanism, which is why this is worth fixing rather than leaving.

Surfaced by the branch review for S14 Maven remote Step 3 (maven_remote_versions schema), which chose to keep the family convention rather than fork one migration.