Skip to content

refactor(cache): slim FieldProjection to (cacheKey, fieldName) (PR-009g-ii) - #1049

Open
AnthonyMDev wants to merge 1 commit into
cache-rewrite/phase-1a-sqlite-projectionfrom
cache-rewrite/phase-1a-projection-slim
Open

refactor(cache): slim FieldProjection to (cacheKey, fieldName) (PR-009g-ii)#1049
AnthonyMDev wants to merge 1 commit into
cache-rewrite/phase-1a-sqlite-projectionfrom
cache-rewrite/phase-1a-projection-slim

Conversation

@AnthonyMDev

Copy link
Copy Markdown
Contributor

Goal

Remove the unconsumed columnShape/cardinality metadata from FieldProjection, making the slim (cacheKey, fieldName) pair the entire 3.0 projection contract.

Design doc reference

  • 0007-selection-aware-cache-reads.md: amended decision (amendment PR forthcoming) — row filtering is the shipped read design; column projection is dropped, position predicates are dropped, and the __typename SQL filter is deferred behind perf measurement.

Position in execution plan

PR-009g-ii of the cache rewrite Phase 1 stack. See cache-rewrite-phase1-execution.md §8.

Stacks on

Followups in this stack

  • ADR 0007 amendment + perf-plan selectFields scenarios (docs PR against cache-rewrite/phase-1-plan)
  • PR-009h: SQLiteNormalizedCache switches to field-aware path + drop-and-rebuild migration

Files changed

  • apollo-ios/Sources/Apollo/Caching/
    • FieldProjection.swift — slimmed to (cacheKey, fieldName); ColumnShape, Cardinality, and all OutputType classification machinery removed
    • NormalizedCache.swift — conflicting-duplicate-projections precondition removed (no longer expressible); stale 1A.5 migration narration rewritten
    • CacheDependentKey.swift, ApolloStore.swift — stale shape/PR-009g references rewritten
  • apollo-ios/Sources/Apollo/Execution/
    • FieldProjectionCollector.swift — constructs slim projections; over-fetch comment now cites the accepted-cost decision
  • apollo-ios/Sources/ApolloSQLite/
    • ApolloSQLiteDatabase.swift — redundant ProjectionKey dedupe struct removed; Set<FieldProjection> used directly
    • SQLiteDatabase.swiftselectFields doc updated (stored shape inferred from position values)
  • Tests/ApolloTests/FieldProjectionTests rewritten for the slim surface; shape arguments removed from LoadFieldsTests, SQLiteSelectFieldsTests, ProjectionLoaderTests, FieldProjectionCollectorTests

Tests added

  • None new — this PR removes API. FieldProjectionTests retains construction, equality, and hashing coverage for the slim type; all existing projection/loader/read-path behavior tests pass unchanged, demonstrating the shape metadata had no behavioral consumers.

Acceptance criteria

  • No references to columnShape/ColumnShape/cardinality/Cardinality remain in apollo-ios/Sources or Tests
  • Set<FieldProjection> dedupes on (cacheKey, fieldName) — the conflicting-duplicates hazard is structurally gone
  • Shape-mismatch behavior (declared vs stored) remains a caller-visible JSONDecodingError.wrongType, matching 2.x

Verification

  • tuist generate succeeds: yes
  • Build green: yes — ApolloTests scheme
  • Tests pass: yes — FieldProjection/Collector/LoadFields/SQLiteSelectFields/ProjectionLoader/ReadWriteFromStore/LoadQueryFromStore/WatchQuery suites (131/131) on Apollo-UnitTestPlan
  • XcodeListNavigatorIssues severity:"error" returns zero: yes
  • New warnings introduced: none

Notes for reviewer

Rationale for dropping (not deferring) column projection: SQLite is row-oriented and the records table is WITHOUT ROWID (clustered whole-row storage), so column narrowing saves no IO — NULL columns cost ~1 header byte each. Position predicates read identical rows on well-formed data; their only effect was converting a declared-vs-stored shape mismatch into a silent refetch, where the intended semantics (per discussion) is the 2.x-matching caller-visible error. If the profile-gated __typename SQL filter is later justified, it requires type-condition metadata that can be added to FieldProjection as an additive, non-breaking property.

🤖 Generated with Claude Code

Removes columnShape and cardinality from FieldProjection, along with
the ColumnShape/Cardinality enums and the OutputType classification
machinery. Per the amended ADR 0007 decision:

- Column projection is dropped, not deferred. SQLite is row-oriented:
  rows live whole in B-tree leaf pages (and the records table is
  WITHOUT ROWID, clustered by primary key), so narrowing the SELECT
  column list saves no IO — a NULL column costs ~1 header byte. The
  savings would be minor per-row CPU, while per-field column sets
  fragment the SQL statement shapes and complicate statement caching.
- Position predicates are dropped. On well-formed data they read
  exactly the rows the row filter already reads (a field has one
  shape at a time). Their only effect was converting a declared-vs-
  stored shape mismatch — a non-backwards-compatible schema change
  shipped without clearing the cache — from a caller-visible
  JSONDecodingError.wrongType into a silent refetch. The error is
  the intended behavior (matching 2.x): the developer decides how to
  respond to a schema change that invalidated their cache.

With no consumer for shape metadata, the slim (cacheKey, fieldName)
pair is the entire 3.0 projection contract for custom NormalizedCache
implementors, and Set<FieldProjection> now dedupes on exactly what
backends read — removing the conflicting-duplicate-projections
precondition hazard. If the profile-gated __typename SQL filter lands
later, it needs type-condition metadata that arrives as an additive
property, not a breaking change.

Also removes the now-redundant ProjectionKey dedupe struct in
ApolloSQLiteDatabase and rewrites stale doc comments that promised
SQL-level projection from PR-009g.

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: f8aa7d26535ead4195702961
Build Logs: View logs

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


✅ 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.

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