Conversation
📝 WalkthroughWalkthrough
ChangesShard claim validation
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Note
Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.
🟡 Other comments (1)
rust/lance/src/dataset/mem_wal/manifest.rs-445-447 (1)
445-447: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winDocument sealed-manifest refusal in
# Errors.
claim_epochnow returns an error for sealed manifests, but this public API’s error contract only documents epoch conflicts, shard-spec conflicts, and contention. Document the sealed refusal and its no-claim effect. As per coding guidelines, “Ensure doc comments match actual semantics; distinguish mutates-in-place (&mut self) from returns-new-value behavior.”🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@rust/lance/src/dataset/mem_wal/manifest.rs` around lines 445 - 447, Update the public `claim_epoch` documentation comment’s `# Errors` section to include refusal for sealed manifests and state that this path makes no claim or mutation. Keep the existing documentation for epoch conflicts, shard-spec conflicts, and contention, and accurately describe the method’s in-place `&mut self` behavior.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Other comments:
In `@rust/lance/src/dataset/mem_wal/manifest.rs`:
- Around line 445-447: Update the public `claim_epoch` documentation comment’s
`# Errors` section to include refusal for sealed manifests and state that this
path makes no claim or mutation. Keep the existing documentation for epoch
conflicts, shard-spec conflicts, and contention, and accurately describe the
method’s in-place `&mut self` behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: QUIET
Plan: Pro Plus
Run ID: eddae87c-eea7-4d35-949b-1203ad196d84
📒 Files selected for processing (1)
rust/lance/src/dataset/mem_wal/manifest.rs
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
hamersaw
left a comment
There was a problem hiding this comment.
I think this change has the right intent, but will not fix underlying issues correctly. It's meant to disallow claiming a table with a different shard_spec_id than the base table. However, Lance currently only uses 0 and 1 as valid values to not manual and automatic sharding configuration. IMO this is part of a larger discussion, we should update the shard spec configuration so that IDs are monotonically increasing. That would make this change valid.
|
Thanks, I think I understand the concern. The manifest-side equality check is only meaningful if every distinct sharding-spec revision has a unique ID. Today the public initialization path assigns It sounds like the prerequisites are:
Would you prefer that I expand this PR to implement the spec-ID lifecycle, or split the monotonic allocation/base-table validation into a prerequisite PR and rebase this change on it? |
6151ec2 to
8a49ce1
Compare
|
Following up on my previous comment: I split the prerequisite work into #8112. #8112 introduces monotonic spec-ID allocation ( The current initializer only creates the first spec, so an empty history produces spec ID Once #8112 lands, I'll rebase #7949 on top of it. #7949 will remain focused on claim-time manifest validation. |
8a49ce1 to
812fe55
Compare
The proto contract promises sharding spec ids are never reused, but the public init path hardcoded id 1 for every automatic sharding configuration, leaving distinct specs indistinguishable at shard-claim time. - add next_spec_id(): greatest id + 1, with 0 reserved as the manual-shard sentinel (MANUAL_SHARD_SPEC_ID) - reject reserved/duplicate spec ids when decoding MemWalIndexDetails - add MemWalIndexDetails::active_sharding_spec() (greatest id) - mem_wal_writer resolves an unset (0) shard_spec_id to the active spec and rejects an explicit mismatch before any shard claim Prerequisite for lance-format#7949.
812fe55 to
0f7bd7f
Compare
The proto contract promises sharding spec ids are never reused, but the public init path hardcoded id 1 for every automatic sharding configuration, leaving distinct specs indistinguishable at shard-claim time. - add next_spec_id(): greatest id + 1, with 0 reserved as the manual-shard sentinel (MANUAL_SHARD_SPEC_ID) - reject reserved/duplicate spec ids when decoding MemWalIndexDetails - add MemWalIndexDetails::active_sharding_spec() (greatest id) - mem_wal_writer resolves an unset (0) shard_spec_id to the active spec and rejects an explicit mismatch before any shard claim Prerequisite for lance-format#7949.
The proto contract promises sharding spec ids are never reused, but the public init path hardcoded id 1 for every automatic sharding configuration, leaving distinct specs indistinguishable at shard-claim time. - add next_spec_id(): greatest id + 1, with 0 reserved as the manual-shard sentinel (MANUAL_SHARD_SPEC_ID) - reject reserved/duplicate spec ids when decoding MemWalIndexDetails - add MemWalIndexDetails::active_sharding_spec() (greatest id) - mem_wal_writer resolves an unset (0) shard_spec_id to the active spec and rejects an explicit mismatch before any shard claim Prerequisite for lance-format#7949.
0f7bd7f to
dc95ea2
Compare
The proto contract promises sharding spec ids are never reused, but the public init path hardcoded id 1 for every automatic sharding configuration, leaving distinct specs indistinguishable at shard-claim time. - add next_spec_id(): greatest id + 1, with 0 reserved as the manual-shard sentinel (MANUAL_SHARD_SPEC_ID) - reject reserved/duplicate spec ids when decoding MemWalIndexDetails - add MemWalIndexDetails::active_sharding_spec() (greatest id) - mem_wal_writer resolves an unset (0) shard_spec_id to the active spec and rejects an explicit mismatch before any shard claim Prerequisite for lance-format#7949.
The proto contract promises sharding spec ids are never reused, but the public init path hardcoded id 1 for every automatic sharding configuration, leaving distinct specs indistinguishable at shard-claim time. - add next_spec_id(): greatest id + 1, with 0 reserved as the manual-shard sentinel (MANUAL_SHARD_SPEC_ID) - reject reserved/duplicate spec ids when decoding MemWalIndexDetails - add MemWalIndexDetails::active_sharding_spec() (greatest id) - mem_wal_writer resolves an unset (0) shard_spec_id to the active spec and rejects an explicit mismatch before any shard claim Prerequisite for lance-format#7949.
The proto contract promises sharding spec ids are never reused, but the public init path hardcoded id 1 for every automatic sharding configuration, leaving distinct specs indistinguishable at shard-claim time. - add next_spec_id(): greatest id + 1, with 0 reserved as the manual-shard sentinel (MANUAL_SHARD_SPEC_ID) - reject reserved/duplicate spec ids when decoding MemWalIndexDetails - add MemWalIndexDetails::active_sharding_spec() (greatest id) - mem_wal_writer resolves an unset (0) shard_spec_id to the active spec and rejects an explicit mismatch before any shard claim Prerequisite for lance-format#7949.
dc95ea2 to
f2ab822
Compare
f2ab822 to
3eaa2e5
Compare
|
Scope and dependency reset completed and force-pushed on latest I narrowed the claim to the identities current Lance code actually emits: manual This PR no longer claims that monotonic spec allocation is a prerequisite or attempts to solve future sharding revisions/activation. #8112 was separately reduced to resolving the writer's default The issue reproducer and tests now use only The existing |
fc60c80 to
27fa780
Compare
27fa780 to
87ea068
Compare
|
@hamersaw PTAL when you have a chance — the open CHANGES_REQUESTED predates the Aug 3 scope reset; the branch is current with |
|
@Xuanwo could you help review this when you have a moment? The CHANGES_REQUESTED (2026-07-27) predates the 2026-08-03 scope reset — the PR is now an independent defensive invariant over the 0/1 shard identities Lance actually emits, no longer gated on monotonic spec-id allocation (that lives in #8112). It's rebased onto current main with the #8640 conflict resolved (the claim path re-validates via |
8e5795f to
bcdf203
Compare
## Summary - resolve the default dataset-writer `shard_spec_id` (`0`) to the MemWAL index's sole automatic sharding spec before creating or claiming a shard manifest - accept an explicit id only when it matches that sole spec, and require manually sharded indexes to keep id `0` - reject metadata with multiple automatic specs because the current writer model supports at most one - cover the original fresh-shard bug at the public `Dataset::mem_wal_writer` boundary plus invalid manual, mismatched, and multiple-spec inputs ## Scope This PR fixes the current writer path only. MemWAL initialization already creates either no spec (manual sharding) or one automatic spec with id `1`; the writer must record that same identity instead of its unresolved default `0`. It does not add monotonic allocation, spec revisions, activation semantics, metadata validation for hypothetical producers, or a file-format change. Those require a separate end-to-end design if a re-shard API is introduced. This PR complements but is not a prerequisite for #7949: this PR resolves the table identity before a fresh manifest is created, while #7949 defensively rejects changing an identity already stored in a manifest. ## Testing - `cargo fmt --all -- --check` - `cargo test -p lance --lib test_writer_shard_spec_resolution_rejects_invalid_identity -- --nocapture` - `cargo test -p lance --lib test_mem_wal_writer_uses_automatic_sharding_spec -- --nocapture` - `cargo clippy --all --tests --benches -- -D warnings` --------- Co-authored-by: Xuanwo <github@xuanwo.io>
bcdf203 to
35db3d1
Compare
35db3d1 to
0b72a5f
Compare
|
Follow-up on codecov's patch-coverage note (94.5%, 3 lines): measured branch coverage locally with Added deterministic coverage (a
All patch lines are now covered ( |
0b72a5f to
c0e8714
Compare
|
CI note: "Python macOS 3.14 ARM" failed in |
c0e8714 to
b76f664
Compare
There was a problem hiding this comment.
✅ Gate recommendation: approve.
The rebase preserves the reviewed patch exactly and does not change the manifest store or its writer/API boundary. The guard still enforces shard identity before epoch mutation and after write conflicts, with #8112 supplying the complementary writer-side resolution. The deterministic conflict tests continue to cover mismatched or sealed state, benign retries, and bounded exhaustion under the updated dependency set.
b76f664 to
7c92d4f
Compare
Summary
shard_spec_idthat differs from the immutable identity already stored in a shard manifest, before advancing manifest version or writer epoch0/1mismatch directions, sealed manifests, and concurrent first claimsScope
This is an independent defensive invariant over the identities Lance currently emits:
0identifies manually managed shards and1is the sole automatic sharding spec. The check does not require monotonic spec allocation and does not define revisions or activation.#8112 (merged) is the complementary creation-side half. It resolves a dataset writer's default
0to the current automatic spec at theDataset::mem_wal_writerboundary, before a fresh manifest is created; this PR prevents any caller from changing an identity once the manifest exists. The layers compose: #8112 guards the API entry point, while this PR guards the stored manifest atclaim_epoch— catching directShardWriter::opencallers that bypass the API boundary.shard_spec_id=0is an identity, not a wildcard.Fixes #7945.
Testing
cargo fmt --all -- --checkcargo test -p lance dataset::mem_wal::manifest::tests --lib -- --nocapture(24 passed on current main; includes the pre-existing perf(mem_wal)!: serve the shard manifest from the store that wrote it #8640-era manifest tests)cargo clippy --all --tests --benches -- -D warningsBehavior change / rollout
Previously, a writer opening an existing shard with a mismatched
shard_spec_id(e.g. the default0opening an auto-sharded shard stored as1) was silently tolerated pastclaim_epoch. It now fails fast withInvalidInputnaming the shard id and both spec ids — this is the fix intent of #7945. With #8112 merged, writers going throughDataset::mem_wal_writerhave their default resolved before claiming, so the hard error only affects callers that bypass the API boundary with an explicitly mismatched id.