Skip to content

Conversation

@kamilkisiela
Copy link
Contributor

@kamilkisiela kamilkisiela commented Jul 16, 2025

by adding type conditions to the FetchNodes

summary of changes -> #279 (comment)

Closes #277

gemini-code-assist[bot]

This comment was marked as outdated.

@github-actions
Copy link

github-actions bot commented Jul 16, 2025

Federation Audit Results

189 tests  ±0   189 ✅ ±0   4s ⏱️ -1s
 42 suites ±0     0 💤 ±0 
 42 files   ±0     0 ❌ ±0 

Results for commit dffbc05. ± Comparison against base commit 7e1c0f6.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jul 16, 2025

GraphQL over HTTP Audit Results

61 tests  ±0   61 ✅ ±0   0s ⏱️ ±0s
 1 suites ±0    0 💤 ±0 
 1 files   ±0    0 ❌ ±0 

Results for commit 983ac7f. ± Comparison against base commit 7e1c0f6.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jul 16, 2025

TestsPassed ✅SkippedFailedTime ⏱
federation-audit | abstract-types.xml18 ran18 ✅423ms
federation-audit | child-type-mismatch.xml4 ran4 ✅90ms
federation-audit | circular-reference-interface.xml2 ran2 ✅49ms
federation-audit | complex-entity-call.xml1 ran1 ✅80ms
federation-audit | corrupted-supergraph-node-id.xml10 ran10 ✅126ms
federation-audit | enum-intersection.xml5 ran5 ✅64ms
federation-audit | fed1-external-extends-resolvable.xml1 ran1 ✅24ms
federation-audit | fed1-external-extends.xml4 ran4 ✅58ms
federation-audit | fed1-external-extension.xml4 ran4 ✅58ms
federation-audit | fed2-external-extends.xml4 ran4 ✅63ms
federation-audit | fed2-external-extension.xml4 ran4 ✅63ms
federation-audit | include-skip.xml4 ran4 ✅88ms
federation-audit | input-object-intersection.xml3 ran3 ✅37ms
federation-audit | interface-object-indirect-extension.xml1 ran1 ✅52ms
federation-audit | interface-object-with-requires.xml7 ran7 ✅112ms
federation-audit | keys-mashup.xml1 ran1 ✅33ms
federation-audit | mutations.xml4 ran4 ✅79ms
federation-audit | mysterious-external.xml2 ran2 ✅52ms
federation-audit | nested-provides.xml2 ran2 ✅34ms
federation-audit | node.xml1 ran1 ✅26ms
federation-audit | non-resolvable-interface-object.xml7 ran7 ✅80ms
federation-audit | null-keys.xml1 ran1 ✅29ms
federation-audit | override-type-interface.xml4 ran4 ✅66ms
federation-audit | override-with-requires.xml4 ran4 ✅90ms
federation-audit | parent-entity-call-complex.xml1 ran1 ✅34ms
federation-audit | parent-entity-call.xml1 ran1 ✅26ms
federation-audit | provides-on-interface.xml2 ran2 ✅39ms
federation-audit | provides-on-union.xml2 ran2 ✅38ms
federation-audit | requires-interface.xml5 ran5 ✅74ms
federation-audit | requires-requires.xml5 ran5 ✅105ms
federation-audit | requires-with-argument.xml5 ran5 ✅103ms
federation-audit | requires-with-fragments.xml6 ran6 ✅97ms
federation-audit | shared-root.xml2 ran2 ✅42ms
federation-audit | simple-entity-call.xml1 ran1 ✅23ms
federation-audit | simple-inaccessible.xml4 ran4 ✅53ms
federation-audit | simple-interface-object.xml13 ran13 ✅173ms
federation-audit | simple-override.xml2 ran2 ✅36ms
federation-audit | simple-requires-provides.xml12 ran12 ✅233ms
federation-audit | typename.xml6 ran6 ✅90ms
federation-audit | unavailable-override.xml2 ran2 ✅36ms
federation-audit | union-interface-distributed.xml10 ran10 ✅101ms
federation-audit | union-intersection.xml12 ran12 ✅140ms

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request fixes an overfetching issue with union types by preserving type cast information in the query plan paths. I've left a few comments, including a critical fix for a compilation error due to a type mismatch when converting MergePath to PlanPathSegment.

@github-actions
Copy link

github-actions bot commented Jul 17, 2025

k6-benchmark results

     ✓ response code was 200
     ✓ no graphql errors
     ✓ valid response structure

     █ setup

     checks.........................: 100.00% ✓ 14895      ✗ 0   
     data_received..................: 438 MB  14 MB/s
     data_sent......................: 5.8 MB  193 kB/s
     http_req_blocked...............: avg=37.88µs  min=1.32µs  med=2.69µs   max=5.93ms   p(90)=4.25µs   p(95)=4.99µs  
     http_req_connecting............: avg=34.08µs  min=0s      med=0s       max=5.87ms   p(90)=0s       p(95)=0s      
     http_req_duration..............: avg=297.65ms min=5.15ms  med=292.61ms max=647.41ms p(90)=378.61ms p(95)=416.92ms
       { expected_response:true }...: avg=297.65ms min=5.15ms  med=292.61ms max=647.41ms p(90)=378.61ms p(95)=416.92ms
     http_req_failed................: 0.00%   ✓ 0          ✗ 4985
     http_req_receiving.............: avg=281.23µs min=38.13µs med=104.94µs max=39.18ms  p(90)=354.95µs p(95)=1.29ms  
     http_req_sending...............: avg=45.78µs  min=8.65µs  med=16.99µs  max=14.59ms  p(90)=27.81µs  p(95)=44.64µs 
     http_req_tls_handshaking.......: avg=0s       min=0s      med=0s       max=0s       p(90)=0s       p(95)=0s      
     http_req_waiting...............: avg=297.32ms min=5.1ms   med=292.46ms max=644.24ms p(90)=377.84ms p(95)=416.83ms
     http_reqs......................: 4985    164.273653/s
     iteration_duration.............: avg=303.43ms min=63.35ms med=293.89ms max=959.25ms p(90)=381.42ms p(95)=425.7ms 
     iterations.....................: 4965    163.614581/s
     vus............................: 50      min=50       max=50
     vus_max........................: 50      min=50       max=50

@kamilkisiela
Copy link
Contributor Author

/gemini review

@kamilkisiela
Copy link
Contributor Author

/gemini summary

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

The code changes introduce type conditions to the FetchNodes, effectively fixing union overfetching. The introduction of FlattenNodePath and FlattenNodePathSegment enhances code clarity and correctness. The comprehensive tests for the new traverse_and_collect logic are commendable.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

This pull request introduces a significant improvement to how union types are handled in query plan execution, specifically addressing the issue of overfetching. By implementing type conditions directly within the FlattenNode's path traversal, the system can now intelligently filter data based on GraphQL's __typename field, leading to more efficient data processing and reduced unnecessary data fetching for union members.

Highlights

  • Core Logic Enhancement: Union Overfetching Fix: The primary goal of this PR is to prevent overfetching for union types. This is achieved by enhancing the traverse_and_collect function in query-plan-executor to incorporate type conditions. It now uses a new FlattenNodePathSegment::Cast variant to filter data based on the __typename field during traversal, ensuring that only relevant data for a specific union member is processed.
  • New Path Representation for Flatten Nodes: Introduced FlattenNodePath and FlattenNodePathSegment (with Field, List, and Cast variants) in query-planner to provide a more structured and expressive way to represent traversal paths within the query plan. The FlattenNode now uses this new path type, allowing for explicit type casting conditions to be embedded directly into the execution path.
  • Improved Path Traversal Utility: The traverse_and_collect utility function in query-plan-executor was significantly refactored to consume the new FlattenNodePathSegment enum. This refactor includes logic to handle field access, list iteration, and crucially, type-based filtering using the __typename field for Cast segments, preventing unnecessary data processing.
  • Updated Path Serialization and Display: The MergePath and FlattenNodePath display and serialization logic were updated to correctly include and represent Cast segments (e.g., |[TypeName]). This ensures that the query plan's string representation and its internal JSON serialization accurately reflect the new type conditions.
  • Comprehensive Testing and New Fixture: New unit tests for the traverse_and_collect function (lib/query-plan-executor/src/tests/traverse_and_collect.rs) were added to validate the new path traversal and type casting logic. A new supergraph fixture (lib/query-planner/fixture/tests/union-overfetching.supergraph.graphql) and a dedicated test case (union_overfetching_test) were introduced to specifically verify the union overfetching fix.
Changelog
  • .cargo/config.toml
    • Added a new test_qpe command for running tests specifically for the query-plan-executor package.
  • lib/query-plan-executor/benches/executor_benches.rs
    • Updated benchmark path definitions to use the new FlattenNodePathSegment enum, aligning with the core logic changes.
  • lib/query-plan-executor/src/lib.rs
    • Refactored traverse_and_collect function to accept &[FlattenNodePathSegment] and implement type-aware data filtering for Cast segments.
    • Introduced contains_typename helper function for __typename checks.
    • Modified ExecutionStep and ParallelNode implementations to utilize the new FlattenNodePath type, removing intermediate string conversions.
  • lib/query-plan-executor/src/tests/mod.rs
    • Included the new traverse_and_collect test module.
  • lib/query-plan-executor/src/tests/traverse_and_collect.rs
    • Added a new file containing extensive unit tests for the traverse_and_collect function, covering various scenarios including field access, list traversal, and type casting.
  • lib/query-planner/fixture/tests/union-overfetching.supergraph.graphql
    • Added a new supergraph schema fixture to enable testing of union overfetching scenarios.
  • lib/query-planner/src/ast/merge_path.rs
    • Added Serialize and Deserialize traits to Condition and Segment enums.
    • Updated the Display implementation for Segment::Cast to use a new |[TypeName] format.
    • Modified path string conversion methods to include Cast segments, which were previously filtered out.
  • lib/query-planner/src/planner/plan_nodes.rs
    • Changed FlattenNode.path type from Vec<String> to the new FlattenNodePath struct.
    • Defined new enums FlattenNodePathSegment (Field, Cast, List) and FlattenNodePath.
    • Implemented From<&MergePath> for FlattenNodePath to convert MergePath segments into the new FlattenNodePath structure, including Cast segments.
    • Updated PrettyDisplay for FlattenNode to use the new FlattenNodePath's display implementation.
  • lib/query-planner/src/tests/*.rs
    • Numerous test snapshots across various test files (e.g., alias.rs, arguments.rs, interface.rs, union.rs) were updated to reflect the new JSON serialization format for FlattenNode paths, now including explicit Field, List, and Cast segments.
Activity
  • Automated Federation Audit Results were posted, showing 177 tests passed, 12 removed, and 1 error.
  • Automated GraphQL over HTTP Audit Results were posted, showing 61 tests passed.
  • Detailed Federation Audit results per XML file were provided by github-actions[bot].
  • Automated k6-benchmark results were posted, indicating all checks passed and providing performance metrics.
  • Author kamilkisiela requested a /gemini review and /gemini summary.
  • A critical review comment from gemini-code-assist[bot] identified a type mismatch in FlattenNodePath conversion, suggesting as_ref().clone() for Arc<String> dereferencing.
  • A medium priority review comment from gemini-code-assist[bot] suggested removing commented-out lines in merge_path.rs for maintainability.
  • A medium priority review comment from gemini-code-assist[bot] recommended making a match statement more concise in plan_nodes.rs using if let with an or-pattern.
  • A medium priority review comment from gemini-code-assist[bot] advised improving flat_map logic in traverse_and_collect by separating filtering and mapping steps.
  • A medium priority review comment from gemini-code-assist[bot] suggested adding a Display implementation for FlattenNode for better debugging and logging.

by adding type conditions to the FetchNodes
@kamilkisiela kamilkisiela marked this pull request as ready for review July 17, 2025 11:42
"product"
{
"Field": "product"
}
Copy link
Member

@ardatan ardatan Jul 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we also get rid of InlineFragment in the require selection set then move that type condition to here?
So instead of having ... on Product in requires selections, we can have { Cast: Product } in the flatten node's path directly, no?

@kamilkisiela kamilkisiela merged commit 1940cbb into main Jul 18, 2025
11 of 12 checks passed
@kamilkisiela kamilkisiela deleted the kamil-conditions branch July 18, 2025 08:52
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.

4 participants