-
Notifications
You must be signed in to change notification settings - Fork 6
fix: handle projection conditions per item in an array, and merge plans nestedly #629
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Summary of ChangesHello @ardatan, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses an issue, ROUTER-235, by refactoring how projection plans are managed within the router's authorization, normalization, and execution phases. The change involves migrating from a simple vector to an ordered map ( Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this 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 introduces a fix for ROUTER-235 by changing the data structure for projection plans from Vec<FieldProjectionPlan> to IndexMap<String, FieldProjectionPlan>. This is a crucial change to correctly handle the merging of fields from different fragments, thus preventing field duplication in the final response. The change is consistently applied across the authorization, normalization, and execution pipelines. A new end-to-end test has been added to reproduce the original issue and verify the fix. The changes are sound and address the problem effectively. I have one suggestion to refactor a loop in the authorization rebuilding logic to improve its readability, in line with the repository's style guide.
✅
|
|
🐋 This PR was built and pushed to the following Docker images: Image Names: Platforms: Image Tags: Docker metadata{
"buildx.build.ref": "builder-90c01579-36cc-49db-b362-66463dfec095/builder-90c01579-36cc-49db-b362-66463dfec0950/qz59t1vq2ifkijtof90fho41e",
"containerimage.descriptor": {
"mediaType": "application/vnd.oci.image.index.v1+json",
"digest": "sha256:624c8ffaf29c6931a85afdf4a9bc031b7a56959168ecbf95db898f5fdba94261",
"size": 1609
},
"containerimage.digest": "sha256:624c8ffaf29c6931a85afdf4a9bc031b7a56959168ecbf95db898f5fdba94261",
"image.name": "ghcr.io/graphql-hive/router:pr-629,ghcr.io/graphql-hive/router:sha-86ccd6b"
} |
5d63d28 to
704979d
Compare
|
This is how I understand the problem. The projection plan expects Since the field projection plan can only reference a single type, then the merged state is broken as it represents only one of the types - That’s why projecting object of type |
|
Replaced by #633 |
Ref ROUTER-235
User reported that they have a schema like following;
And when they send the following query;
The subgraph returns the following data;
{ "contentPage": { "contentBody": [ { "id": "container1", "section": { "__typename": "ContentA", "id": "contentA1", "contentChildren": [] } }, { "id": "container2", "section": { "__typename": "ContentB", "id": "contentB1", "contentChildren": [ { "title": "contentBChild1" } ] } } ] } }But the router responds like below;
{ "contentPage": { "contentBody": [ { "id": "container1", "section": { "__typename": "ContentA", "id": "contentA1", "contentChildren": [] } }, { "id": "container2", "section": { "__typename": "ContentB", "id": "contentB1", "contentChildren": null } } ] } }Initially I assumed that the subgraph returns the data with
__typenameslike below;And I saw that projection puts
nulltocontentChildrenon the second item because it expectsContentBChildbut it getsContentAChild. I realized that something is wrong with the plan merging logic when it is nested, it was duplicating the fields in the plan so for each possible type, the field is serialized like"id": "value", "id": "value"because it wasn't merging the same fields when they are nested (so it can have multiple plans for the same field).So I did a refactor to apply the plan merging nestedly but in order to do that I needed to convert
Vecusage toIndexMapwhich is needed by merging logic. Then this ended up changing allVec<Plan>types toIndexMaps.The merging was fine but it was still getting
ContentBChilds typename asContentAChildbecause it couldn't get__typenamefrom the array and it was usingplan.field_typeas a fallback incorrectly. Then I did another refactor to apply condition checking for arrays item-by-item instead of using the fallback value directly, because fallback value was always the first possible item of the abstract field type (ContentAChild) in our case while it can beContentBChild.Then the first test started passing as expected but the user's issue is not still solved. Why? Because it was never sending __typename s for non-abstract values because planner didn't need it to be sent. So I dropped the fallback logic for __typename, and check for __typenames only when it is there which made fallback logic unnecessary and I dropped
field_typefrom the projection plan entirely.So the second test case which is user's actual issue started passing.
While working on this, I dropped unnecessary Arc usage, and added a helper function
get_value_by_keyto reduce some duplicate logic in the code, I also improved tracing messages so we can get more information about projection condition checks.