Skip to main content

omnigraph/db/
mod.rs

1pub mod commit_graph;
2pub mod graph_coordinator;
3pub mod manifest;
4mod omnigraph;
5mod recovery_audit;
6mod schema_state;
7pub(crate) mod write_queue;
8
9pub use commit_graph::GraphCommit;
10pub use graph_coordinator::{GraphCoordinator, ReadTarget, ResolvedTarget, SnapshotId};
11pub use manifest::{Snapshot, SubTableEntry, SubTableUpdate};
12pub(crate) use omnigraph::ensure_public_branch_ref;
13pub use omnigraph::{
14    CleanupPolicyOptions, InitOptions, MergeOutcome, Omnigraph, OpenMode, RepairAction,
15    RepairClassification, RepairOptions, RepairStats, SchemaApplyOptions, SchemaApplyResult,
16    SkipReason, TableCleanupStats, TableOptimizeStats, TableRepairStats,
17};
18
19pub(crate) const SCHEMA_APPLY_LOCK_BRANCH: &str = "__schema_apply_lock__";
20
21/// Mutation kind, threaded through the version-check call sites so the
22/// engine can apply an op-kind-aware policy:
23///
24/// - `Insert` / `Merge`: skip the strict pre-stage `ensure_expected_version`
25///   check. Lance's `MergeInsertBuilder` rebases concurrent appends; the
26///   per-(table, branch) writer queue serializes `commit_staged`; the
27///   publisher's CAS (refreshed under the queue via
28///   `MutationStaging::commit_all`'s `snapshot_for_branch` call) catches
29///   genuine cross-process drift as `ManifestConflictDetails::ExpectedVersionMismatch`.
30///   The pre-stage strict check would over-reject in-process concurrent
31///   inserts, which is exactly the case PR 2 / MR-686 designed the
32///   per-table queue to allow.
33///
34/// - `Update` / `Delete`: keep the strict check. These have read-modify-write
35///   semantics; Lance moving between the read at stage time and the write
36///   at commit time means the staged batch is computed against stale state.
37///   The strict check guards the per-query SI invariant. SERIALIZABLE
38///   opt-in (§VI.36 future seam) is the long-term answer for tighter
39///   semantics; today, in-process update-update races on the same key
40///   stay rejected as 409 — acceptable.
41///
42/// - `SchemaRewrite`: keep the strict check. Schema apply runs under the
43///   graph-wide `__schema_apply_lock__` AND per-table queues; the strict
44///   check is uncontested at that point.
45#[derive(Debug, Clone, Copy, PartialEq, Eq)]
46pub(crate) enum MutationOpKind {
47    Insert,
48    Merge,
49    Update,
50    Delete,
51    SchemaRewrite,
52}
53
54impl MutationOpKind {
55    /// Whether the strict pre-stage `ensure_expected_version` check should
56    /// fire for this op kind. See [`MutationOpKind`] for the rationale per
57    /// kind.
58    pub(crate) fn strict_pre_stage_version_check(self) -> bool {
59        match self {
60            MutationOpKind::Insert | MutationOpKind::Merge => false,
61            MutationOpKind::Update | MutationOpKind::Delete | MutationOpKind::SchemaRewrite => true,
62        }
63    }
64}
65
66pub(crate) fn is_schema_apply_lock_branch(name: &str) -> bool {
67    name.trim_start_matches('/') == SCHEMA_APPLY_LOCK_BRANCH
68}
69
70pub(crate) fn is_internal_system_branch(name: &str) -> bool {
71    // Legacy `__run__*` staging branches (Run state machine, removed MR-771)
72    // are swept off `__manifest` by the v2→v3 internal-schema migration, so the
73    // only internal branch the engine still creates is the schema-apply lock.
74    is_schema_apply_lock_branch(name)
75}