Conversation
Merged
pathscale
pushed a commit
that referenced
this pull request
Sep 9, 2026
Collapses what was PR #102 onto the arctic, event-ledger and page-list work already on this branch, so WorkTable carries one pull request. #97, #99 and #100 are folded in; #58 is not, being 224 commits behind master and already conflicted, which is its own job. `fsx` and every persistence signature go through `nagoya::io`, so the production path names no runtime. A persisted table can set `page_size`, which was refused before because the seeks computed offsets from a crate constant while the generated table threaded the configured one. Four places where the folded branches disagreed, each resolved by keeping both rather than either: * `arctic` and `ps-reclaim` keep #97's raised version floors and gain the `default-features = false` the no_std work needs. * `allocated_bytes` keeps the page list as #100 left it and takes `core::mem` from the no_std work; the `.load()` in the older branch belonged to a shape #100 replaced. * `batch.rs` and `task.rs` take the `core`/`alloc` imports, plus the `Arc` and `Location` the no_std lists had dropped and the code still uses. * The s3 test goes back to tokio's extension traits. It talks to a tokio `TcpStream` it starts itself, so the sweep that took the storage path off tokio should never have touched it. `event_ledger` is new here and was written against `std`. Its bookkeeping moves to `core` and `alloc`; only the two parts that genuinely need an operating system are gated, the backtrace capture and reading `WT_EVENT_LEDGER`, so without `std` the ledger is simply never enabled. `futures/std` goes in this crate's own `std` feature rather than on the dependency line, where a `--no-default-features` build would still have turned it on. cargo test --workspace --all-targets 933 passed ... --all-features 935 passed ... --features versioned-row-publication 1029 passed cargo clippy --workspace --all-targets [--all-features] clean cargo check --no-default-features clean
This was referenced Sep 9, 2026
Closed
Owner
Author
|
Folded into #105 as commits 20 to 23, rebased onto the current tree and green. Both original commits replay with their authorship intact. Two files moved rather than merged: codegen/src/common/{model,parser}/columnar.rs are now dsl/src/{model,parser}/columnar.rs, because that crate was extracted into worktable_dsl after this was written. Everything else is present unchanged, guide and PDF included, verified by blob hash. Two bugs were fixed on the way in: worktable_dsl::schema had no columnar_indexes arm, so a valid declaration generated code and was then rejected by gen_schema_const; and src/columnar.rs broke --no-default-features by importing std paths and emitting std::collections::BTreeSet into generated code. |
pathscale
pushed a commit
that referenced
this pull request
Sep 10, 2026
The columnar rebase dropped PR #58's `ColumnSlotIdExhausted` rollback from `reinsert` and `reinsert_cdc`, on the judgement that this tree swings the primary index only after every index check passes, so re-inserting the old link would write an entry the failure path never removed. That judgement was never re-derived, and a dropped rollback in a persistence path is the change that shows up as corruption on reload rather than as a failing operation. Two claims, asserted rather than read. A failed insert leaves no primary index entry, and the key it used is free afterwards, which is the observable consequence of the entry having actually been removed rather than merely being unreadable. And an update at capacity does not fail at all, because `replace_row` reuses the row's own slot, which is what makes the dropped rollback unreachable for a live row rather than merely unlikely. Taking `primary_index.remove` back out of the insert arm turns the test red with `PrimaryAlreadyExists`, so it fails for the reason it exists.
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Storage-flavor boundary
WorkTable now has a clear three-flavor model:
This PR deliberately implements the low-cost middle flavor. It does not claim to be a full column store.
Summary
columnarsyntax without introducing a table layout switchcolumnar_indexeswith one meaningful key declaration:cluster_byconfig.columnar_slot_idandconfig.columnar_chunk_rowsColumnSlotId8|16|32|64, defaulting to 32 bits, without replacing the primary keyBTreeMapside-index metadataIdentity and correctness
ColumnSlotIduses the full configured width only as a compact side-vector position. It is neither sort rank nor durable identity.ColumnarRowRefis opaque and validates:This closes the same-primary-key delete/reinsert ABA hole without reducing the configured live-slot capacity. Generation never wraps; an exhausted generation permanently retires that slot. The table incarnation rejects references from a different or reopened instance. Only
primary_key()is public, and the reference is not serializable.Choosing a slot width large enough for maximum simultaneously live columnar rows is the schema author's responsibility. Exhaustion returns
WorkTableError::ColumnSlotIdExhausted(bits), rolls back the authoritative mutation, and never widens, truncates, wraps, evicts, or panics.DSL corrections from expert review
columnaruses the table chunk defaultcolumns: [...]inside a side index is rejected as semantically redundantincludeis reserved and rejected until covering projection existscompression(none)is accepted; inertauto/delta/rle/dictionarydeclarations are errorscolumnar, unknown/non-columnar cluster keys, duplicate config, method-name collisions, unknown postfix attributes, and unsupportedworktable_version!syntax are rejectedCurrent implementation boundary
Vec<Vec<Option<T>>>; no SIMD/vector kernel, validity bitmap, string arena, codec, or native side-index disk format is claimedVecvalues and materialize the resultscan_batchesare follow-upsRwLockgives each operation a coherent side-index snapshot but serializes concurrent side-index writerscolumnar_is_dirty()andrebuild_columnar()let applications schedule the current whole-table rebuild costSAP HANA comparison
The v3 guide compares this work with Sikka et al., Efficient Transaction Processing in SAP HANA Database: The End of a Column Store Myth (SIGMOD 2012). HANA's L1 row delta → L2 column delta → compressed main lifecycle is precedent for a future full-columnar flavor. The honest analogy here is narrower: WorkTable retains its tabular engine and adds optional uncompressed side indexes; it does not implement HANA's L2/main lifecycle or vector execution.
Validation
cargo test --all-features: 171 library tests passed; 524 integration tests passed, 5 intentionally ignored; 2 doctests passedUsingcoverage passes with WorkTablesIndex, congee, and arctic primary backendscargo clippy --all-targets --all-features -- -D warningscargo check --no-default-featurescargo fmt --all -- --checkDocuments
docs/columnar-index-plan.md— implementation plan and scope boundarydocs/columnar-fields-and-indexes-guide-v3.md— complete technical/reviewer guide, including the HANA comparisonoutput/pdf/worktable-columnar-side-indexes-guide-v3.pdf— visually reviewed 9-page PDFPerformance claims remain gated on the
wt-benchmarksmatrix: tabular baseline vs fields-only vs fields-plus-clustered side indexes, row-path overhead, p50/p95/p99, concurrency, allocations, memory, code size, dirty rebuild, persisted reload, and all supportedUsingbackends.