fix(query-planner): restore missing defer dependencies after transitive reduction#9123
Open
fix(query-planner): restore missing defer dependencies after transitive reduction#9123
Conversation
Contributor
✅ Docs preview has no changesThe preview was not built because there were no changes. Build ID: 560c66488c0a0589718af1c4 ✅ AI Style Review — No Changes DetectedNo MDX files were changed in this pull request. Review Log: View detailed log
|
Contributor
|
@duckki, please consider creating a changeset entry in |
…ve reduction When the fetch dependency graph's transitive reduction removes a direct edge from an ancestor fetch to a deferred node (because a transitive path exists through an intermediate fetch), the ancestor is not registered as a defer dependency. At runtime, the deferred node never receives the ancestor's data (__typename, entity keys), causing the deferred fetch to be silently skipped. Track defer-crossing edges removed during reduction and restore them as dependencies when the ancestor's selection set has intersection with the deferred target's required inputs.
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.
Background
When the query planner builds a fetch dependency graph for queries with
@defer, it performs a transitive reduction to eliminate redundant edges. However, when a direct edge from an ancestor fetch to a deferred fetch node is also reachable transitively through an intermediate fetch, the reduction removes the direct edge. This causes extract_children_and_deferred_dependencies to miss registering the ancestor as a defer dependency, so at runtime the deferred node never receives the ancestor's broadcast data (__typename, entity keys, and other fields at that response path). The deferred fetch is then silently skipped, returning null for fields that should have data.Proposal
The fix tracks defer-crossing edges that are removed during transitive reduction in a new reduced_defer_edges field on FetchDependencyGraph. After reduction, collect_reduced_defer_dependencies examines each removed edge: it navigates the source fetch's selection set down to the target's merge_at level using selection_set_at_path, then checks whether the source provides any fields the deferred target's inputs require (using SelectionMap::get() with SelectionKey for type-condition-aware matching). Only edges where a real field intersection exists are restored as dependencies, avoiding unnecessary over-registration.
Testing
The change includes two new federation-level snapshot tests—one for the original reproducer where the intermediate fetch has a deeper merge_at path, and one where the intermediate has the same merge_at as the deferred target—plus a router-level integration test that exercises the full defer execution pipeline and verifies the deferred response is not silently dropped.
Checklist
Complete the checklist (and note appropriate exceptions) before the PR is marked ready-for-review.