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
Downafter the child is already dropped fails withERROR: relation "partitions.maven_remote_versions_p63" does not exist. DROP TABLE IF EXISTS partitions.<table>_p63on its own already removes the partition from the hierarchy (pg_inheritsgoes 64 → 63) and replays as aNOTICEno-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
DETACHstatements each — 1408 statements total. - The shared helper
assertDownDropsEveryPartitionAndParent(internal/datastore/migrations/schema_helpers_test.go) actively asserts exactly 64DETACHes plus a per-partition by-nameDETACHcheck, 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
- Drop the 64
DETACH PARTITIONstatements from eachDownsection, relying onDROP TABLE IF EXISTS partitions.<table>_pNN. - Update
assertDownDropsEveryPartitionAndParentto 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.