Implement RFC-022 unified graph write protocol (#343)

* Implement unified graph write protocol

* Preserve recovery error wire compatibility
This commit is contained in:
Andrew Altshuler 2026-07-11 14:02:54 +03:00 committed by GitHub
parent 0c8d769501
commit f758ff0d17
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
80 changed files with 13393 additions and 2050 deletions

View file

@ -21,6 +21,12 @@ properties in the assignment block (`insert WorksAt { person: $p, org: $o }`).
`<value>` is a literal, `$param`, or `now()`.
On a blob-bearing type, an update materializes and rewrites blob payloads only
for the rows matched by its predicate, including blobs the update does not
change. This keeps correctness independent of physical index state, but adds
read/write I/O proportional to the matched blob bytes; use selective update
predicates for large blobs.
## Atomicity
A change query publishes **one commit** at the end of the query. Multiple
@ -29,6 +35,19 @@ failure leaves the graph untouched. See [transactions](../branching/transactions
for the per-query atomicity contract and [branches](../branching/index.md) for
multi-query workflows.
Concurrent changes use optimistic concurrency over the whole target branch.
Insert/Merge/Append operations whose branch changed before physical effects are
discarded and fully revalidated with a bounded internal retry. Strict
Update/Delete/Overwrite operations instead return a structured conflict. This
branch-wide token is deliberately conservative: a change to a different table
can invalidate a prepared strict write because constraints may have read it.
If the synchronous barrier finds an unresolved overlapping recovery intent, or
if a conflict is discovered after a Lance table effect is durable, the request
returns `recovery_required` with an operation id. Do not immediately retry that
request; reopen the graph read-write (or restart the server) so the durable
recovery intent is resolved first.
## Inserts/updates and deletes cannot mix in one query
A single change query must be **either insert/update-only or delete-only**.