Files
clockwork-labs-bot 91d6d5bfca Fix primary key migration causing stale schema (#3934) (#4666)
## Summary

Fixes #3934. Removing or changing a `#[primary_key]` annotation succeeds
on the first re-publish, but the stored schema's `table_primary_key`
field in `st_table` is never updated. On the **next** publish,
`check_compatible` fails with:

```
Primary key mismatch: self.primary_key: Some(ColId(0)), def.primary_key: None
```

## Root Cause

`auto_migrate_table` handles removing the PK's index and unique
constraint, but there was no `AutoMigrateStep` to update the
`table_primary_key` field in the system table.

## Fix

- Add `AutoMigrateStep::ChangePrimaryKey` variant to the auto-migration
planner
- Detect `old.primary_key != new.primary_key` in `auto_migrate_table`
and emit the step
- Add `alter_table_primary_key` to the datastore layer (`mut_tx`,
`datastore`, `relational_db`) with proper rollback support via
`PendingSchemaChange::TableAlterPrimaryKey`
- Handle the step in `auto_migrate_database`
- Add migration plan formatter support (termcolor output)

## Repro Script

```bash
# 1. Publish with primary key
spacetime publish repro --yes  # table has #[primary_key] on name

# 2. Remove primary key — succeeds
spacetime publish repro --yes  # removed #[primary_key]

# 3. Any change — CRASHES
spacetime publish repro --yes  # Primary key mismatch error
```

## Tests

- **Unit test** in `crates/core/src/db/update.rs`: Reproduces the exact
three-publish sequence from the issue (create table with PK → remove PK
→ trivial change)
- **Smoketest** in
`crates/smoketests/tests/smoketests/auto_migration.rs`: Full end-to-end
publish flow exercising the same scenario

## Files Changed

| File | Change |
|------|--------|
| `crates/schema/src/auto_migrate.rs` | Add `ChangePrimaryKey` variant +
detection |
| `crates/schema/src/auto_migrate/formatter.rs` | Format the new step |
| `crates/schema/src/auto_migrate/termcolor_formatter.rs` | Colored
output |
| `crates/datastore/src/locking_tx_datastore/tx_state.rs` |
`TableAlterPrimaryKey` pending change |
| `crates/datastore/src/locking_tx_datastore/mut_tx.rs` |
`alter_table_primary_key` |
| `crates/datastore/src/locking_tx_datastore/datastore.rs` | Expose
through datastore |
| `crates/datastore/src/locking_tx_datastore/committed_state.rs` |
Rollback support |
| `crates/core/src/db/relational_db.rs` | Expose through RelationalDB |
| `crates/core/src/db/update.rs` | Handle step + unit test |
| `crates/smoketests/.../auto_migration.rs` | Smoketest |

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-04-14 21:07:38 +00:00
..
2025-10-24 16:34:13 +00:00
2025-10-24 16:34:13 +00:00