feat(odf): a write takes the cached result of what reads it away - #888
Open
andiwand wants to merge 1 commit into
Open
feat(odf): a write takes the cached result of what reads it away#888andiwand wants to merge 1 commit into
andiwand wants to merge 1 commit into
Conversation
andiwand
force-pushed
the
feat/stale-formulas
branch
from
September 11, 2026 22:15
1147bf7 to
0eeb6b3
Compare
andiwand
force-pushed
the
feat/ods-stale-cache
branch
from
September 11, 2026 22:16
7102637 to
ae5ed82
Compare
An edited input leaves every formula reading it computing an old number, and the saved file went on showing the result its producer cached. ODF states no switch asking a reader to recompute - ooxml's `fullCalcOnLoad`, which every xlsx save already sets - so the result goes instead: a cell stating a formula and no result is one a reader has to compute, and none can show a wrong number for. `drop_stale_results` asks `SheetDependencies` which cells read the written position, directly or through another formula, and takes the attributes stating a value off each. The `text:p` showing it goes as an element rather than as a node, so the registry keeps no dangling one. The formula, the cell's style and a drawing anchored in the cell all stay. A formula whose references could not be read keeps its result: nothing says it is wrong, and blanking every one of them on an unrelated edit would cost more than it is worth. Until the evaluator lands, a cleared cell renders empty here too. The spike, as far as a CLI can answer it: LibreOffice's `--convert-to` recomputes whatever a file cached - a hand-edited wrong result came back corrected - so it cannot show what a reader that does not recompute would display, and its `ODFRecalcMode` setting changed nothing. An end-to-end check confirms the saved package is valid and that LibreOffice computes the cell we cleared. Step 3.4 of `docs/design/spreadsheet-editing.md`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VVmjmddv2Ui17Nptc1ggue
andiwand
force-pushed
the
feat/ods-stale-cache
branch
from
September 11, 2026 22:18
ae5ed82 to
f105f4d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖 Generated with Claude Code
Stacked on #887 → #886 → #885 → #884 — this PR's diff is the fifth commit. Last of the step-3 stack.
Step 3.4 of
docs/design/spreadsheet-editing.md.The problem
An edited input leaves every formula reading it computing an old number, and the saved
.odswent on showing the result its producer cached. An.xlsxhas a switch for exactly this —calcPr/@fullCalcOnLoad, which every save already sets. ODF has none.What it does
So the result goes instead.
drop_stale_resultsasksSheetDependencieswhich cells read the written position — directly or through another formula — and takes the attributes stating a value off each. Thetext:pshowing it goes as an element rather than as a node, so the registry keeps no dangling one.The formula, the cell's style and a drawing anchored in the cell all stay. A cell stating a formula and no result is one a reader has to compute, and none can show a wrong number for.
A formula whose references could not be read keeps its result. Nothing says it is wrong, and blanking every named-range formula on an unrelated edit would cost more than it is worth.
Document::unresolved_formulas()is what names them.The cost until step 4: a cleared cell renders empty here too. That is the trade the design accepted — an empty cell says "not computed", a stale one says nothing.
The spike, as far as a CLI can answer it
LibreOffice's
--convert-torecomputes whatever a file cached — a file whose cached result I hand-edited to999converted back to3— so it cannot show what a reader that does not recompute would display, and settingODFRecalcModeto "never" in a scratch profile changed nothing. ODF states no recalculation switch at all, so the rule the file itself can carry is what is left.End-to-end check: a real LibreOffice-written
.ods, edited throughSheet::set_celland saved by us, opens as a valid package and LibreOffice computes the cell we cleared (10 / 2 / 12, where the file states no result for the third).Test
test/src/internal/odf/odf_sheet_stale_test.cpp, 7 cases from inline fixtures: the direct reader, the chain, a formula reading something else, a reader on another sheet, what the cell keeps, the saved file, and a write nothing reads.Reference output: as said on #887, the output repos get one commit and one pin advance after the whole stack has landed.