Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
95125f5
feat(transaction): add the Transaction V2 action vocabulary
wjones127 Aug 15, 2026
a6de85e
feat(transaction): carry action-based operations through the wire
wjones127 Aug 16, 2026
8d54184
refactor(table): extract manifest assembly helpers from build_manifest
wjones127 Aug 16, 2026
687868d
feat(transaction): apply the minting actions
wjones127 Aug 16, 2026
9312a61
feat(transaction): apply the reference-stable actions
wjones127 Aug 16, 2026
5045999
feat(transaction): compute conflict footprints for action sets
wjones127 Aug 16, 2026
c8669ed
feat(commit): resolve action-set conflicts by footprint
wjones127 Aug 16, 2026
0b85d92
test(transaction): cover relocating an action set onto a newer version
wjones127 Aug 16, 2026
b15ff8f
test(commit): end-to-end composite transactions against a real dataset
wjones127 Aug 16, 2026
ae8a940
feat(transaction): add the DropField action
wjones127 Aug 17, 2026
4489ad9
refactor(transaction): give each action its own module
wjones127 Aug 17, 2026
2f4c1eb
feat(transaction): add the ReserveFragmentIds action
wjones127 Aug 17, 2026
aaf03d5
feat(transaction): add the ResetTable action
wjones127 Aug 17, 2026
46c4c42
feat(transaction): add the ConfigUpdate action
wjones127 Aug 17, 2026
78ab19a
refactor(transaction): rename UserOperation to CompositeOperation
wjones127 Aug 18, 2026
2e446a5
docs(transaction): document when action version and data_change field…
wjones127 Aug 18, 2026
d8dbd0a
refactor(transaction): generate the action dispatch from one list
wjones127 Aug 18, 2026
01fa03c
test(lance): move composite transaction tests into the library
wjones127 Aug 18, 2026
ff053e5
docs(transaction): give the real reason SetDeletionFile takes no Ref
wjones127 Aug 18, 2026
2e2bfd1
refactor(transaction): split applying actions from assembling the man…
wjones127 Aug 18, 2026
e90f9c2
feat(transaction): reference fields by Ref in the field actions
wjones127 Aug 18, 2026
b4a9420
fix(transaction): adapt the action path to upstream API changes
wjones127 Aug 19, 2026
29176fa
feat(transaction): add a fragment at a reserved id
wjones127 Sep 2, 2026
7f7ef94
feat(transaction): add the ReserveRowIds action
wjones127 Sep 2, 2026
6173731
fix(transaction): run MemWAL coverage invalidation on the action path
wjones127 Sep 10, 2026
5e8907b
feat(commit): gate composite operations behind a caller opt-in
wjones127 Sep 20, 2026
26403ac
test(commit): cover the rest of the action vocabulary end to end
wjones127 Sep 20, 2026
16b9280
docs(transaction): give the action vocabulary worked examples
wjones127 Sep 20, 2026
278e042
docs(transaction): call Transaction V2 experimental, not a draft
wjones127 Sep 21, 2026
048de9d
docs(transaction): warn that committing V2 breaks pre-v12 readers
wjones127 Sep 21, 2026
ff8ecab
fix(transaction): report base name and path collisions separately
wjones127 Sep 21, 2026
a43801d
refactor(transaction): type AlterField::logical_type as LogicalType
wjones127 Sep 21, 2026
4142c19
refactor(transaction): take the current manifest by reference in apply
wjones127 Sep 21, 2026
413c943
docs(transaction): point the stable row id error at the migration
wjones127 Sep 21, 2026
61fc55b
fix(transaction): let a dataset hold more than one unnamed base path
wjones127 Sep 21, 2026
9abec50
refactor(transaction): stop stamping the envelope's identity onto the…
wjones127 Sep 21, 2026
83c943b
docs(protos): correct the Transaction V2 support note
wjones127 Sep 21, 2026
2f8d830
feat(commit): gate Transaction V2 writes behind an unstable env var
wjones127 Sep 21, 2026
5f423f0
fix(transaction): require the definition of a field whose data a set …
wjones127 Sep 22, 2026
9998adf
docs(transaction): say why a reservation writes no coordinate
wjones127 Sep 22, 2026
2e43669
fix(transaction): close the field-scoped gaps in the action footprint
wjones127 Sep 22, 2026
d23bb97
test(transaction): share the pair-test footprint helper and cover res…
wjones127 Sep 23, 2026
eeb9508
refactor(transaction): compare footprints through one mode table
wjones127 Sep 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/src/format/table/transaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,11 @@ same id, name, or path.
opt-in for exactly this reason, and a table that has one anywhere in its
history raises the minimum reader version for that table to v12.0.0.

Writing is gated twice while the feature is experimental: the calling code
opts in per commit, and the deployment sets
`LANCE_ENABLE_UNSTABLE_TRANSACTION_V2` in the environment. Release builds
refuse without both.

Every operation above is a single named verb. A transaction may instead carry a
`CompositeOperation`: an ordered list of granular *actions* that apply
atomically as one manifest change. This lets one commit express a change no
Expand Down
5 changes: 5 additions & 0 deletions java/lance-jni/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,11 @@ fn convert_to_java_operation_inner<'local>(
&[JValue::Object(&new_bases)],
)?)
}
// Transaction V2 is a pre-vote draft with no Java surface yet; a
// composite operation has no Java class to map onto.
Operation::CompositeOperation(_) => Err(Error::unsupported_error(
"CompositeOperation transactions are not exposed to the Java bindings".to_string(),
)),
}
}

Expand Down
5 changes: 3 additions & 2 deletions protos/transaction/actions.proto
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ package lance.table;
* atomically as one manifest change. This is an experimental feature under
* the process in docs/src/community/voting.md: the field numbers are not a
* stable contract, may change without a separate vote, and are removed if
* the stabilization vote does not pass. Support here is read-side
* fail-closed — rejected on load, with no write path.
* the stabilization vote does not pass. Reading is fail-closed: an action
* this build does not recognize aborts the load rather than being skipped.
* Writing is opt-in, for the reason below.
*
* COMPATIBILITY WARNING. A table version carrying one of these cannot be
* opened at all by Lance before v12.0.0, and the fix is not backported
Expand Down
18 changes: 18 additions & 0 deletions rust/lance-table/src/feature_flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,24 @@ pub(crate) const STICKY_PAIRED_FLAGS: u64 = FLAG_MIXED_DATA_FILE_VERSIONS;
/// overlay files before the feature is generally released.
pub const ENABLE_UNSTABLE_DATA_OVERLAY_FILES_ENV: &str = "LANCE_ENABLE_UNSTABLE_DATA_OVERLAY_FILES";

/// Environment variable that opts a release build into committing Transaction
/// V2 (an action-based [`CompositeOperation`]) before the feature is generally
/// released.
///
/// This gates the writer only. It lives here so every
/// `LANCE_ENABLE_UNSTABLE_*` switch is discoverable in one place, even though
/// Transaction V2 has no manifest flag bit of its own.
///
/// [`CompositeOperation`]: crate::transaction::action::CompositeOperation
pub const ENABLE_UNSTABLE_TRANSACTION_V2_ENV: &str = "LANCE_ENABLE_UNSTABLE_TRANSACTION_V2";

/// Whether this build may commit Transaction V2: always in debug builds, so
/// tests exercise the path, and in release builds only when
/// [`ENABLE_UNSTABLE_TRANSACTION_V2_ENV`] is set.
pub fn transaction_v2_enabled() -> bool {
cfg!(debug_assertions) || std::env::var_os(ENABLE_UNSTABLE_TRANSACTION_V2_ENV).is_some()
}

/// Set the reader and writer feature flags in the manifest based on the contents of the manifest.
pub fn apply_feature_flags(
manifest: &mut Manifest,
Expand Down
30 changes: 17 additions & 13 deletions rust/lance-table/src/format/fragment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,22 @@ impl TryFrom<pb::DeletionFile> for DeletionFile {
}
}

impl From<&DeletionFile> for pb::DeletionFile {
fn from(value: &DeletionFile) -> Self {
let file_type = match value.file_type {
DeletionFileType::Array => pb::deletion_file::DeletionFileType::ArrowArray,
DeletionFileType::Bitmap => pb::deletion_file::DeletionFileType::Bitmap,
};
Self {
read_version: value.read_version,
id: value.id,
file_type: file_type.into(),
num_deleted_rows: value.num_deleted_rows.unwrap_or_default() as u64,
base_id: value.base_id,
}
}
}

/// Data fragment.
///
/// A fragment is a set of files which represent the different columns of the same rows.
Expand Down Expand Up @@ -717,19 +733,7 @@ impl TryFrom<pb::DataFragment> for Fragment {

impl From<&Fragment> for pb::DataFragment {
fn from(f: &Fragment) -> Self {
let deletion_file = f.deletion_file.as_ref().map(|f| {
let file_type = match f.file_type {
DeletionFileType::Array => pb::deletion_file::DeletionFileType::ArrowArray,
DeletionFileType::Bitmap => pb::deletion_file::DeletionFileType::Bitmap,
};
pb::DeletionFile {
read_version: f.read_version,
id: f.id,
file_type: file_type.into(),
num_deleted_rows: f.num_deleted_rows.unwrap_or_default() as u64,
base_id: f.base_id,
}
});
let deletion_file = f.deletion_file.as_ref().map(pb::DeletionFile::from);

let row_id_sequence = f.row_id_meta.as_ref().map(|m| match m {
RowIdMeta::Inline(data) => {
Expand Down
2 changes: 2 additions & 0 deletions rust/lance-table/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
//! ```text
//! builder Transaction: an operation plus the version it was based on
//! operation the vocabulary of changes an operation can describe
//! action the finer-grained Transaction V2 vocabulary (experimental)
//! update_map incremental edits to the manifest's string maps
//! validate pre-commit checks against the manifest being replaced
//! manifest_build applying an operation to produce the next manifest
Expand All @@ -26,6 +27,7 @@
//! proto the persisted protobuf encoding of all of the above
//! ```

pub mod action;
mod builder;
mod conflicts;
mod index_maintenance;
Expand Down
Loading
Loading