Skip to content

Commit 3581796

Browse files
fix(migrations): m008 also widens checkpoint PK to (bus_name, subscriber_id)
Without this, fresh-DB setups would have bus_name added but the PK would remain (subscriber_id), causing ON CONFLICT (bus_name, subscriber_id) to fail at runtime. Adding the PK widening here ensures it runs in the correct order (after the table is created by m003).
1 parent c3beb1e commit 3581796

1 file changed

Lines changed: 39 additions & 5 deletions

File tree

epoch_pg/src/migrations/m008_add_bus_name_to_checkpoints.rs

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
//! Migration 008: Add `bus_name` column to `epoch_event_bus_checkpoints`.
1+
//! Migration 008: Add `bus_name` column and widen the PK to `(bus_name, subscriber_id)`.
22
//!
3-
//! Required for the composite checkpoint key `(bus_name, subscriber_id)` so that
4-
//! per-domain buses (each with their own `events_table`) maintain isolated
5-
//! checkpoint rows in the shared table.
6-
//! Existing rows are backfilled to `'epoch_events'` (the legacy default).
3+
//! Required for per-domain buses — each bus uses its own `events_table` as the
4+
//! `bus_name` key so checkpoints remain isolated in the shared table.
5+
//! Existing rows are backfilled to `'epoch_events'` (the legacy default), then the
6+
//! default is dropped so every new insert must supply an explicit value.
77
88
use async_trait::async_trait;
99
use sqlx::{Postgres, Transaction};
@@ -23,6 +23,7 @@ impl Migration for AddBusNameToCheckpoints {
2323
}
2424

2525
async fn up<'a>(&self, tx: &mut Transaction<'a, Postgres>) -> Result<(), MigrationError> {
26+
// Add bus_name with a backfill default for existing rows.
2627
sqlx::query(
2728
r#"
2829
ALTER TABLE epoch_event_bus_checkpoints
@@ -32,6 +33,39 @@ impl Migration for AddBusNameToCheckpoints {
3233
.execute(&mut **tx)
3334
.await?;
3435

36+
// Widen the PK to (bus_name, subscriber_id).
37+
// Drop the legacy single-column PK constraint first (name may vary after the
38+
// m004 rename, so we handle both names).
39+
sqlx::query(
40+
"ALTER TABLE epoch_event_bus_checkpoints \
41+
DROP CONSTRAINT IF EXISTS epoch_event_bus_checkpoints_pkey",
42+
)
43+
.execute(&mut **tx)
44+
.await?;
45+
sqlx::query(
46+
"ALTER TABLE epoch_event_bus_checkpoints \
47+
DROP CONSTRAINT IF EXISTS event_bus_checkpoints_pkey",
48+
)
49+
.execute(&mut **tx)
50+
.await?;
51+
52+
// Add the composite PK (idempotent: if it somehow already exists, this is a no-op
53+
// at the migration-runner level because this migration only runs once).
54+
sqlx::query(
55+
"ALTER TABLE epoch_event_bus_checkpoints \
56+
ADD PRIMARY KEY (bus_name, subscriber_id)",
57+
)
58+
.execute(&mut **tx)
59+
.await?;
60+
61+
// Drop the column default now that all rows carry an explicit value.
62+
sqlx::query(
63+
"ALTER TABLE epoch_event_bus_checkpoints \
64+
ALTER COLUMN bus_name DROP DEFAULT",
65+
)
66+
.execute(&mut **tx)
67+
.await?;
68+
3569
Ok(())
3670
}
3771
}

0 commit comments

Comments
 (0)