Commit 40af039
committed
feat: Allow toggling event flag during auto-migration for empty tables
## Summary
Currently, toggling `#[spacetimedb::table(event)]` on an existing table
fails with `AutoMigrateError::ChangeTableEventFlag` and requires a
manual migration. This PR allows the flip in either direction as a
live auto-migration step when the table has zero committed rows.
Non-empty tables fail with an actionable error guiding the user to
clear the table first. Clients are disconnected on the flip because
the change is observable to subscribers (event tables have no
committed state).
## Changes
- **`tx_state.rs`**: New `PendingSchemaChange::TableAlterEventFlag`
variant storing the old `is_event` value for rollback.
- **`committed_state.rs`**: Rollback branch restores the old value on
the live schema.
- **`mut_tx.rs`**: New `alter_table_event_flag` — dual-write to the
tx + commit table schemas and to `st_event_table`. Idempotent
no-op early returns before pushing a pending change. New
`delete_st_event_table_row` helper using the existing
`delete_col_eq` utility (hits the unique btree index on col 0).
- **`replay.rs`**: New hook on `ST_EVENT_TABLE_ID` insert/delete
mirrors `reschema_table_for_st_table_update` — flips `is_event`
on the referenced user-table's cached schema during replay. This
is load-bearing for cold replay across the flip point.
- **`relational_db.rs`**: Thin `alter_table_event_flag` wrapper.
- **`auto_migrate.rs`**: `event_ok` error branch replaced with
`AutoMigrateStep::ChangeEventFlag` + `ensure_disconnect_all_users`.
Removed dead `AutoMigrateError::ChangeTableEventFlag` variant.
- **`formatter.rs` / `termcolor_formatter.rs`**: New
`format_change_event_flag` mirroring `format_change_access`.
- **`update.rs`**: New `ChangeEventFlag` handler with an O(1)
row-count precheck before any mutation.
## Safety
- **Transaction safety**: Precheck (row count) and all three writes
(st_event_table, tx schema, commit schema) run in the same `MutTx`.
- **Rollback**: `TableAlterEventFlag` stores the old flag value so
failed txs revert `is_event` on the live schema. Idempotent flips
do not push a pending change.
- **Replay correctness**: Without the replay hook, cold replay from
a pre-migration snapshot would miss the schema flip and
post-migration inserts would silently land in committed state.
The hook mirrors the existing `st_table`/`st_column` pattern.
- **Client contract**: Flipping `event` changes observability — v1
subscribers stop seeing updates; v2 subscribers see a different
message variant. `ensure_disconnect_all_users` forces reconnection.
## Example error output
```
Cannot change `event` flag on table `my_table`: table contains data.
Clear the table's rows (e.g. via a reducer) before toggling the
`event` annotation.
```
## Test plan
- [x] `cargo test -p spacetimedb-datastore --features test` — 87 pass
(including 4 new `alter_table_event_flag` tests)
- [x] `cargo test -p spacetimedb-schema` — 103 pass (including 3 new
`change_event_flag` plan tests)
- [x] `cargo test -p spacetimedb-core` — 192 pass (including 2 new
empty/non-empty integration tests)
- [x] `cargo clippy -p spacetimedb-datastore -p spacetimedb-schema -p spacetimedb-core --tests` clean
- [x] Pre-existing event-table tests still pass (10 tests)1 parent 2d67d76 commit 40af039
10 files changed
Lines changed: 507 additions & 29 deletions
File tree
- crates
- core/src/db
- datastore/src/locking_tx_datastore
- schema/src
- auto_migrate
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
989 | 989 | | |
990 | 990 | | |
991 | 991 | | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
| 995 | + | |
992 | 996 | | |
993 | 997 | | |
994 | 998 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
282 | 282 | | |
283 | 283 | | |
284 | 284 | | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
285 | 306 | | |
286 | 307 | | |
287 | 308 | | |
| |||
339 | 360 | | |
340 | 361 | | |
341 | 362 | | |
| 363 | + | |
342 | 364 | | |
343 | 365 | | |
344 | 366 | | |
| |||
580 | 602 | | |
581 | 603 | | |
582 | 604 | | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
583 | 713 | | |
Lines changed: 5 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
921 | 921 | | |
922 | 922 | | |
923 | 923 | | |
| 924 | + | |
| 925 | + | |
| 926 | + | |
| 927 | + | |
| 928 | + | |
924 | 929 | | |
925 | 930 | | |
926 | 931 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
320 | 320 | | |
321 | 321 | | |
322 | 322 | | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
323 | 331 | | |
324 | 332 | | |
325 | 333 | | |
| |||
1011 | 1019 | | |
1012 | 1020 | | |
1013 | 1021 | | |
1014 | | - | |
| 1022 | + | |
1015 | 1023 | | |
1016 | 1024 | | |
1017 | 1025 | | |
| |||
3181 | 3189 | | |
3182 | 3190 | | |
3183 | 3191 | | |
| 3192 | + | |
| 3193 | + | |
| 3194 | + | |
| 3195 | + | |
| 3196 | + | |
| 3197 | + | |
| 3198 | + | |
| 3199 | + | |
| 3200 | + | |
| 3201 | + | |
| 3202 | + | |
| 3203 | + | |
| 3204 | + | |
| 3205 | + | |
| 3206 | + | |
| 3207 | + | |
| 3208 | + | |
| 3209 | + | |
| 3210 | + | |
| 3211 | + | |
| 3212 | + | |
| 3213 | + | |
| 3214 | + | |
| 3215 | + | |
| 3216 | + | |
| 3217 | + | |
| 3218 | + | |
| 3219 | + | |
| 3220 | + | |
| 3221 | + | |
| 3222 | + | |
| 3223 | + | |
| 3224 | + | |
| 3225 | + | |
| 3226 | + | |
| 3227 | + | |
| 3228 | + | |
| 3229 | + | |
| 3230 | + | |
| 3231 | + | |
| 3232 | + | |
| 3233 | + | |
| 3234 | + | |
| 3235 | + | |
| 3236 | + | |
| 3237 | + | |
| 3238 | + | |
| 3239 | + | |
| 3240 | + | |
| 3241 | + | |
| 3242 | + | |
| 3243 | + | |
| 3244 | + | |
| 3245 | + | |
| 3246 | + | |
| 3247 | + | |
| 3248 | + | |
| 3249 | + | |
| 3250 | + | |
| 3251 | + | |
| 3252 | + | |
| 3253 | + | |
| 3254 | + | |
| 3255 | + | |
| 3256 | + | |
| 3257 | + | |
| 3258 | + | |
| 3259 | + | |
| 3260 | + | |
| 3261 | + | |
| 3262 | + | |
| 3263 | + | |
| 3264 | + | |
| 3265 | + | |
| 3266 | + | |
| 3267 | + | |
| 3268 | + | |
| 3269 | + | |
| 3270 | + | |
| 3271 | + | |
| 3272 | + | |
| 3273 | + | |
| 3274 | + | |
| 3275 | + | |
| 3276 | + | |
| 3277 | + | |
| 3278 | + | |
| 3279 | + | |
| 3280 | + | |
| 3281 | + | |
| 3282 | + | |
| 3283 | + | |
| 3284 | + | |
| 3285 | + | |
| 3286 | + | |
| 3287 | + | |
| 3288 | + | |
| 3289 | + | |
| 3290 | + | |
| 3291 | + | |
| 3292 | + | |
| 3293 | + | |
| 3294 | + | |
| 3295 | + | |
| 3296 | + | |
| 3297 | + | |
| 3298 | + | |
| 3299 | + | |
| 3300 | + | |
| 3301 | + | |
| 3302 | + | |
| 3303 | + | |
| 3304 | + | |
| 3305 | + | |
| 3306 | + | |
| 3307 | + | |
| 3308 | + | |
| 3309 | + | |
| 3310 | + | |
| 3311 | + | |
| 3312 | + | |
| 3313 | + | |
| 3314 | + | |
| 3315 | + | |
| 3316 | + | |
| 3317 | + | |
| 3318 | + | |
| 3319 | + | |
| 3320 | + | |
| 3321 | + | |
| 3322 | + | |
| 3323 | + | |
| 3324 | + | |
| 3325 | + | |
| 3326 | + | |
| 3327 | + | |
| 3328 | + | |
| 3329 | + | |
| 3330 | + | |
| 3331 | + | |
| 3332 | + | |
| 3333 | + | |
| 3334 | + | |
| 3335 | + | |
| 3336 | + | |
| 3337 | + | |
| 3338 | + | |
| 3339 | + | |
| 3340 | + | |
| 3341 | + | |
| 3342 | + | |
| 3343 | + | |
| 3344 | + | |
| 3345 | + | |
| 3346 | + | |
| 3347 | + | |
| 3348 | + | |
| 3349 | + | |
| 3350 | + | |
| 3351 | + | |
3184 | 3352 | | |
3185 | 3353 | | |
3186 | 3354 | | |
| |||
0 commit comments