This repository was archived by the owner on Aug 3, 2026. It is now read-only.
fix: worktable_version! does not compile for an unsized primary key - #178
Merged
Conversation
added 2 commits
August 1, 2026 06:01
The read-only table generator emitted the PersistTable derive attribute as either #[table(pk_unsized)] or #[table(read_only)], never both. The two flags are independent: read_only selects the read-only shape (no persistence engine or task, sync into_worktable, 1-tuple table struct), pk_unsized selects the unsized primary index. A read-only table with an unsized key needs both, so picking pk_unsized silently dropped read_only and generated the full persist shape against a read-only table struct. The result was that worktable_version! did not compile at all for any table whose primary key is not fixed-size, a String key being the common case: load() called a sync into_worktable() that had been generated as async and returning Self(table, PersistenceTask), against a struct with one field. Fixed by emitting #[table(read_only, pk_unsized)]; the attribute parser already accepts both, and every downstream read_only branch already composes with pk_unsized. The sized path is unchanged. This was never caught because tests/worktable_version/basic.rs, the only user of the macro, uses u64 primary_key autoincrement.
Ships the worktable_version! fix for unsized primary keys. The macro did not compile for any table whose key is not fixed-size, which is every table that keys on a String, so no schema migration could be written against one. Bumps worktable and worktable_codegen to 0.9.3 with the exact pin.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
worktable_version!fails to compile for any table whose primary key is notfixed-size. A
Stringkey is the common case, and it is the case that matters:a table keyed on a
Stringcannot have a schema migration written against it atall. Changing only the key type takes the same macro invocation from 0 errors to 4.
Cause
read_onlyandpk_unsizedare independent flags on thePersistTablederive.read_onlyselects the read-only shape: no persistence engine or task, a syncinto_worktable(), and a 1-tuple table struct.pk_unsizedseparately selectsthe unsized primary index.
The read-only table generator emitted them as if they were mutually exclusive
(
codegen/src/generators/read_only/table/mod.rs), so an unsized key silentlydropped
read_onlyand generated the full persist shape against a read-onlytable struct.
load()then called aninto_worktable()that had been generatedas async and returning
Self(table, PersistenceTask), against a struct with onefield, which is exactly the four errors above.
The generator type is not involved.
pk_gen_state()emittingself.0.pk_gen.get_state()unconditionally is fine, since the state impl existsfor every generator including
GeneratorType::None.Fix
Emit
#[table(read_only, pk_unsized)]. The attribute parser already accepts bothvia
parse_nested_meta, and every downstreamread_onlybranch already composeswith
pk_unsized:into_worktable's read-only arm uses the sharedprimary_index_init, and the engine and task types return empty regardless. Thesized path is byte-for-byte unchanged.
Tests
Two, both verified to fail before the fix and pass after:
tests/worktable_version/string_primary_key.rswrites two rows through apersisted
String-keyed table, reloads them throughworktable_version!, andasserts on both a full scan and a lookup by string key. Without the fix it
reproduces the four errors verbatim.
codegen/src/worktable_version/mod.rsgains a unit test asserting the emittedattribute keeps
read_onlyfor an unsized key.The path was never covered because
tests/worktable_version/basic.rs, the onlyuser of the macro, uses
u64 primary_key autoincrement.Release
Bumps
worktableandworktable_codegento 0.9.3 with the exact pin, matchingthe 0.9.2 release commit.
CHANGELOG.mdis untouched, consistent with the 0.9.xreleases. Publishing is left for a human to run from merged
masterperAGENTS.md.
Verification
cargo test320 passed / 0 failed / 4 ignored (the 4 ignores are pre-existing andannotated as such on
master), 115 unit and 45 codegen tests pass,cargo clippy --all-targetsclean,cargo fmt --checkclean.