Skip to content

docs(cache): amend ADR 0007 — row filtering adopted, column projection dropped - #1050

Open
AnthonyMDev wants to merge 13 commits into
cache-rewrite/phase-1-planfrom
cache-rewrite/phase-1a-adr-0007-amend-ii
Open

docs(cache): amend ADR 0007 — row filtering adopted, column projection dropped#1050
AnthonyMDev wants to merge 13 commits into
cache-rewrite/phase-1-planfrom
cache-rewrite/phase-1a-adr-0007-amend-ii

Conversation

@AnthonyMDev

Copy link
Copy Markdown
Contributor

Goal

Amend ADR 0007 so the documented design matches the shipped PR-009 stack and the decisions settled in review: row filtering is the accepted read design, column projection and position predicates are dropped (with rationale), and the __typename SQL filter is deferred behind named perf scenarios.

Design doc reference

  • 0007-selection-aware-cache-reads.md — new "Amendments" section carries the full rationale; Principles 1/3/6/7, Alternatives B/F, the codegen migration note, and the implementation-sequence rows for PR-009b/f/g are updated in place with amendment markers.
  • cache-rewrite-phase1-perf.md §2 Tier 2 — four new loadFields scenarios (projected load, projected batch load, projected list load, inline-fragment over-fetch). The over-fetch scenario is the explicit decision gate for the deferred __typename filter and PR-009g-bis.

Position in execution plan

ADR amendment (docs PR against cache-rewrite/phase-1-plan, per the ADR-PR merge cadence). Companion to code PR #1049 (PR-009g-ii).

Stacks on

  • cache-rewrite/phase-1-plan

Followups in this stack

Files changed

  • apollo-ios/Design/adr/0007-selection-aware-cache-reads.md
  • apollo-ios/Design/cache-rewrite-phase1-perf.md

Tests added

None (docs).

Acceptance criteria

  • ADR no longer claims the __typename CTE "landed in PR-009g"
  • Amended Principles 1/3 describe the shipped row-filter semantics, including shape-mismatch = caller-visible wrongType (2.x-matching)
  • The __typename filter and PR-009g-bis share a named, runnable measurement gate in the perf plan
  • PR-009f row describes the shipped CacheDependentKey design

Verification

  • Docs-only change; links checked relative to apollo-ios/Design/.

Notes for reviewer

The one decision this amendment deliberately does not make: the final disposition of loadRecords(forKeys:) and the @_spi(Execution) gates on loadFields/FieldProjection/selectFields. The Decision section now carries an explicit pointer noting that's resolved at PR-009h / API freeze. Everything else in the amendment reflects decisions already settled in review discussion.

🤖 Generated with Claude Code

…n dropped

Records the 2026-07-13 amendment:

- Alternative B (row filtering with wide column projection) is the
  accepted read design; what PR-009g shipped is the intended shape,
  not a transition state. Column projection is dropped with the
  row-oriented-storage rationale (WITHOUT ROWID clustered rows; NULL
  columns cost ~1 header byte; narrowing saves no IO and fragments
  statement shapes), and it would have been incorrect against the
  shipped encoding regardless (null/custom-scalar/enum/integral-float
  column routing).
- Position predicates are dropped: zero effect on well-formed data;
  declared-vs-stored shape mismatch stays a caller-visible
  JSONDecodingError.wrongType matching 2.x, by choice.
- Principle 7 (custom-scalar column declaration) withdrawn; no
  codegen change needed.
- Alternative F's rationale corrected: the __typename CTE did NOT
  land in PR-009g. It is deferred behind the new Tier 2 loadFields
  perf scenarios (added to the perf plan, including the
  inline-fragment over-fetch scenario that gates both the CTE and
  PR-009g-bis) and would arrive as an additive requiredTypename
  property.
- Principle 6 / PR-009f row corrected to describe the shipped
  CacheDependentKey design.
- Implementation sequence gains the PR-009g-ii slim row (#1049).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@apollo-librarian

apollo-librarian Bot commented Jul 13, 2026

Copy link
Copy Markdown

✅ Docs preview ready

The preview is ready to be viewed. View the preview

File Changes

0 new, 4 changed, 0 removed
* (developer-tools)/ios/(latest)/fetching/persisted-queries.mdx
* (developer-tools)/ios/(latest)/tutorial/tutorial-connect-queries-to-ui.mdx
* (developer-tools)/ios/(latest)/tutorial/tutorial-define-additional-mutations.mdx
* (developer-tools)/ios/(latest)/tutorial/tutorial-paginate-results.mdx

Build ID: e5e75ea82c0524696ce6df2f
Build Logs: View logs

URL: https://www.apollographql.com/docs/deploy-preview/e5e75ea82c0524696ce6df2f


✅ AI Style Review — No Changes Detected

No MDX files were changed in this pull request.

Review Log: View detailed log

This review is AI-generated. Please use common sense when accepting these suggestions, as they may not always be accurate or appropriate for your specific context.

AnthonyMDev and others added 5 commits July 13, 2026 14:59
… parsing

Adds an INV-001 slot to §8: replacing JSONSerialization behind
JSONSerializationFormat.deserialize is the Linux-portability enabler
for the response path and would eliminate per-scalar NSNumber boxing,
retiring SQLiteFieldEncoding's bridged-number classification. Wide
blast radius (runtime type of every JSONValue), so it's tracked as a
go/no-go investigation gated before the 3.0 final tag rather than
slipped into Phase 1A.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…gates

delete-then-write in writeFieldOrList is a correctness-over-throughput
choice (~2N B-tree mutations per overwrite vs ~N for upsert +
range-prune). Revisit after PR-011's Tier 2/3 write measurements; if
kept, remove upsertRow's dead ON CONFLICT clause (the preceding
delete makes conflicts impossible).

Also pins a PR-009h design requirement: the field-level diff computed
by mergeRecords must survive to the row layer — insertOrUpdate should
receive partial Records of changed fields only, coordinated with the
writtenAt-refresh persistence fix so TTL timestamp advances persist.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Prepared-statement caching for ApolloSQLiteDatabase's row-per-element
statements, landing before PR-011 so the perf gates measure the cached
shape. Consolidating the three cascade-CTE walks rides along, per
review.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Actor + custom serial executor (UnownedJob recipe, iOS-15-compatible;
SwiftNIO precedent) replaces the DispatchQueue + reentrancy token and
moves blocking SQLite IO off the shared cooperative pool. Gated on the
PR-009h / API-freeze checkpoint because the public SQLiteDatabase
protocol becomes async throws.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Resolves the public-surface question the 2026-07-13 amendment deferred:
the final 3.0 protocols expose only loadFields. PR-009h removes
loadRecords, deletes the delegating default, graduates loadFields +
FieldProjection to public, and gives InMemoryNormalizedCache a native
implementation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
AnthonyMDev and others added 7 commits July 16, 2026 13:55
…-iii)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ation rejection

Records two 2026-07-28 review outcomes: PR-009g-bis's gate should
weigh correctness-by-construction (eliminating the two-pass agreement
obligation) alongside the perf measurement; and denormalizing child
typenames onto CacheReferences was considered and rejected because
path-keyed records can change runtime type, making pointer-copied
typenames stale — the record's own __typename row plus the read-time
SQL filter remains the design.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d cache hits

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…yped @fieldPolicy docs

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ache-hit fetch signal

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… as pending

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ache hits

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant