Commit 3017e09
fix(databases): sync non-indexed attributes on worker-restart schema reload (RE-7) (#1183)
* fix(databases): sync non-indexed attributes in initStores() on resetDatabases() (RE-7)
`initStores()` only merged indexed attributes back into `table.attributes`
when updating an existing table (e.g. after a hot-reload–triggered
`resetDatabases()`). Non-indexed, non-primary-key fields (e.g. `name: String`,
`breed: String`) were written to `attributesDbi` by `table()` in the
restarted worker and signalled via ITC, but the main thread's
`resetDatabases()` → `initStores()` path skipped them — leaving
`describe_database` returning only the old attribute list until a full
kill+restart.
Fix: extend the existing-table update loop in `initStores()` to add/replace
non-indexed attributes as well as indexed ones, and remove them when they
are no longer present in the persisted schema.
Adds two regression tests in schemaMigrationFragility.test.js (RE-7 suite).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(databases): fix RE-7 regression test to actually exercise the INSERT path
The previous setup called table() with all four attributes, which populated
Table.attributes before resetDatabases() ran. initStores() always found
existingIdx >= 0, so the INSERT path (existingIdx < 0) was never reached
and the test passed with or without the fix.
Now simulates the true RE-7 mismatch: after table() writes all four attrs to
attributesDbi, reset in-memory Table.attributes back to [id] to mirror the
stale main-thread state that exists after a worker-only restart. resetDatabases()
must now re-sync from attributesDbi, exercising the INSERT path.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(databases): address PR review — use attribute.attribute and fix removal test
- resources/databases.ts: use `attribute.attribute` instead of `attribute.name`
in the non-indexed attribute findIndex (per cb1kenobi's suggestion; `attribute.name`
can be falsey for attributes that arrive with only the `attribute` field set).
- unitTests/resources/schemaMigrationFragility.test.js: fix removal regression test —
after `table()` updates in-memory Table.attributes, re-create the stale main-thread
state (still holding breed/age) before calling resetDatabases(), so the removal loop
in initStores() is actually exercised.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* style: run prettier on schemaMigrationFragility test
* fix(databases): preserve runtime-only relationship attrs on resetDatabases() (RE-7)
The removal loop in initStores() was dropping runtime-only attributes — like
relationship attrs added via GraphQL `@relationship` — because table()'s
persistence loop intentionally `continue`s past them (databases.ts:1138), so
they appear in `existingAttributes` (table.attributes) but not in the
`attributes` list rebuilt from attributesDbi. updatedAttributes() then stripped
the resolver/search support, breaking nested GraphQL queries after any
resetDatabases() / hot-reload — the symptom that showed up in CI as 8 failing
`handles query by nested attribute` assertions in graphql-querying-test and the
404/501 RESTProperties failures.
Also fixes a splice-while-iterating bug in the same loop: splicing the array
being walked by `for...of` skipped the next element, so two adjacent removals
(e.g. `breed` and `age` in the regression test) only dropped one. The loop now
collects into `toRemove` and applies the splices after iteration.
Adds a unit test that injects a relationship attr and asserts it survives a
resetDatabases() call, and extends the removal test's comment to explain why
the two-adjacent-removal pattern is intentional.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(databases): set attributesUpdated on non-indexed attribute update path
When an existing non-indexed attribute was already present in
existingAttributes (existingIdx >= 0) and got replaced by the splice,
attributesUpdated was never set to true. As a result the schemaVersion
bump and updatedAttributes() call at line 682 were skipped, leaving
downstream code with stale property resolvers when a plain field's
type/nullability changed via hot-reload.
The add path (existingIdx < 0) was already correct; this brings the
update path into parity.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>1 parent c000908 commit 3017e09
2 files changed
Lines changed: 148 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
620 | 620 | | |
621 | 621 | | |
622 | 622 | | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
623 | 637 | | |
624 | 638 | | |
625 | 639 | | |
626 | 640 | | |
627 | 641 | | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
628 | 646 | | |
629 | 647 | | |
630 | 648 | | |
| |||
645 | 663 | | |
646 | 664 | | |
647 | 665 | | |
648 | | - | |
649 | | - | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
650 | 675 | | |
651 | 676 | | |
652 | 677 | | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
653 | 682 | | |
654 | 683 | | |
655 | 684 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
382 | 382 | | |
383 | 383 | | |
384 | 384 | | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
385 | 502 | | |
386 | 503 | | |
387 | 504 | | |
| |||
0 commit comments