docs(writes): name ensure_writable_or_defer in the op-kind policy comment

The MutationOpKind doc comment still named the old ensure_expected_version
check; the strict pre-stage precondition is now ensure_writable_or_defer, which
tolerates benign content-preserving drift and rejects only a stale caller pin.
Update the Insert/Merge, Update/Delete, and SchemaRewrite rationale to match so
a reader greps to the right function.
This commit is contained in:
Ragnor Comerford 2026-06-08 11:44:47 +02:00
parent d69b15d975
commit 954b5453d1
No known key found for this signature in database

View file

@ -20,27 +20,30 @@ pub(crate) const SCHEMA_APPLY_LOCK_BRANCH: &str = "__schema_apply_lock__";
/// Mutation kind, threaded through the version-check call sites so the
/// engine can apply an op-kind-aware policy:
///
/// - `Insert` / `Merge`: skip the strict pre-stage `ensure_expected_version`
/// check. Lance's `MergeInsertBuilder` rebases concurrent appends; the
/// per-(table, branch) writer queue serializes `commit_staged`; the
/// publisher's CAS (refreshed under the queue via
/// `MutationStaging::commit_all`'s `snapshot_for_branch` call) catches
/// genuine cross-process drift as `ManifestConflictDetails::ExpectedVersionMismatch`.
/// The pre-stage strict check would over-reject in-process concurrent
/// inserts, which is exactly the case PR 2 / MR-686 designed the
/// per-table queue to allow.
/// - `Insert` / `Merge`: skip the strict pre-stage write precondition
/// (`Omnigraph::ensure_writable_or_defer`). Lance's `MergeInsertBuilder`
/// rebases concurrent appends; the per-(table, branch) writer queue
/// serializes `commit_staged`; the publisher's CAS (refreshed under the
/// queue via `MutationStaging::commit_all`'s `snapshot_for_branch` call)
/// catches genuine cross-process drift as
/// `ManifestConflictDetails::ExpectedVersionMismatch`. The pre-stage check
/// would over-reject in-process concurrent inserts, which is exactly the
/// case PR 2 / MR-686 designed the per-table queue to allow.
///
/// - `Update` / `Delete`: keep the strict check. These have read-modify-write
/// semantics; Lance moving between the read at stage time and the write
/// at commit time means the staged batch is computed against stale state.
/// The strict check guards the per-query SI invariant. SERIALIZABLE
/// opt-in (§VI.36 future seam) is the long-term answer for tighter
/// semantics; today, in-process update-update races on the same key
/// - `Update` / `Delete`: keep the strict precondition. These have
/// read-modify-write semantics, so the staged batch must be computed against
/// current committed state. The OCC fence is the *fresh* manifest pin: a
/// stale handle (the caller's view is behind the live manifest) is rejected
/// as 409 before any staged commit, while benign content-preserving drift
/// (Lance HEAD ahead of the manifest with no recovery sidecar) is tolerated.
/// SERIALIZABLE opt-in (§VI.36 future seam) is the long-term answer for
/// tighter semantics; today, in-process update-update races on the same key
/// stay rejected as 409 — acceptable.
///
/// - `SchemaRewrite`: keep the strict check. Schema apply runs under the
/// graph-wide `__schema_apply_lock__` AND per-table queues; the strict
/// check is uncontested at that point.
/// - `SchemaRewrite`: keep the strict precondition. Schema apply runs under the
/// graph-wide `__schema_apply_lock__` AND per-table queues; the check is
/// uncontested at that point (it tolerates benign drift and defers only on a
/// foreign recovery sidecar).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum MutationOpKind {
Insert,
@ -51,9 +54,9 @@ pub(crate) enum MutationOpKind {
}
impl MutationOpKind {
/// Whether the strict pre-stage `ensure_expected_version` check should
/// fire for this op kind. See [`MutationOpKind`] for the rationale per
/// kind.
/// Whether the strict pre-stage write precondition
/// (`Omnigraph::ensure_writable_or_defer`) should fire for this op kind.
/// See [`MutationOpKind`] for the rationale per kind.
pub(crate) fn strict_pre_stage_version_check(self) -> bool {
match self {
MutationOpKind::Insert | MutationOpKind::Merge => false,