Repository navigation
Index rows decode with no graph: stamp it once at the range-read choke point #2078
Description
Index rows come back from a range read with g: None: fluree-db-query/src/binary_range.rs builds every index row without a graph, so a caller that reads .g off a range result has to stamp the graph by hand, and the ones that didn't have each been their own named-graph bug. So far: the whole-graph scan, the annotation bundle seal (stamp_graph in stage.rs), the seal scan in #1887, #2022's net-change fold through current_asserted_for_key, and #2008's conflict retractions, which read through CurrentFacts and its stored() stamp. Each is fixed at its own site, or will be once #1887 lands, but the class isn't closed, and one instance is still open on main: push validation's is_currently_asserted (fluree-db-api/src/commit_transfer.rs) skips any range row whose g differs from the target's, so an index row never matches a named-graph target, and a pushed commit that retracts an index-resident named-graph fact is refused ("retract targets non-existent assertion").
- Stamp the graph once, where every
GraphDbRef/range_with_overlaycaller already passes:range_with_overlay_trackedandrange_bounded_with_overlayinfluree-db-core/src/range.rs, which both have the snapshot and theg_id. That also fixes push validation. - Drop the manual stamps that become redundant (
stage.rs'sstamp_graph, the whole-graph scan's;CurrentFacts'sstored()keeps recording the origin). - Look at the two decode sites outside that choke point:
binary_history.rs(the history API; its output may exposeg) andblock_fetch.rs(raw block transport, a wire payload, which I'd leave alone). - Tests: a range read over an indexed named graph returns stamped rows, and a push that retracts an index-resident named-graph fact is accepted.
On cost: Flake's PartialEq, Hash and comparators exclude g, so stamping only changes code that reads .g, and default-graph reads (g_id 0) don't change. Per row it's one Arc clone. Per named-graph range call it's resolving g_id to a Sid, and GraphRegistry stores IRIs only, so that's an IRI encode per call unless we add a small Sid cache (or callers that already know the graph Sid pass it). One-read-per-slot callers, like a wide named-graph delete, would pay that per slot without the cache, so this wants a before/after on named-graph-heavy shapes (a named-graph delete-all at 20k, SHACL over a named graph) before it lands. The estimate is about 40–60 lines plus the cache.
cc @bplatz, since #2022's fold reads through this path too.
Found while reviewing #2008 (the "index rows carry no graph" class).
Activity