-
Notifications
You must be signed in to change notification settings - Fork 257
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
incorrect query plan generated when spreading interface fragment into multiple implementations #396
Comments
It's possible this is related to #384, but there's not quite enough information there for me to know. |
@benjaminjkraft Do you know if this is still happening on the latest version of |
Not intended to be merged as such, just to run the test per discussion in the issue.
You got it: apollographql/apollo-server#4281. From a quick look, it looks like it is still happening. (Edit: removed what I previously wrote here -- I had misread the diff.) |
…f specific scope)
The query planner associate to each occurrence of a field in a query a "scope". That scope records a so-called "parent type" as well as all the types the object could have when reaching that field. For instance, with: ```graphql { ... on X { ... on Z { f } } ... on Y { ... on Z { f } } } ``` the planner associate `Z` as parent type of both occurrences of `f` ( because it's mot the "immediate" condition applied to it in both cases), but also record that the 1st occurrence is necessary a `X` while it is necessary a `Y` in the 2nd occurrence. When handling fields a particular level, the planner groups fields by field name and parent type. In the case above, it treats both occurrences of `f` together, because they have the same parent type `Z`. However, when treating that group, the planner incorrectly ignores the fact that while the parent types are the same, the scope are not fully similar, and it only handles the 1st occurrence of the field. As a result, the generated plan ends up only fetching the first occurrence, which is incorrect (concretely, the gateway never return `Y` objects while it should). This commit fixes the problem by changing the way fields are grouped. Instead of being grouped just by parent type, they are grouped by their scope. So, in the example above, both occurrences of `f` are treated separately. Fixes: apollographql#396
The query planner associate to each occurrence of a field in a query a "scope". That scope records a so-called "parent type" as well as all the types the object could have when reaching that field. For instance, with: ```graphql { ... on X { ... on Z { f } } ... on Y { ... on Z { f } } } ``` the planner associate `Z` as parent type of both occurrences of `f` ( because it's mot the "immediate" condition applied to it in both cases), but also record that the 1st occurrence is necessary a `X` while it is necessary a `Y` in the 2nd occurrence. When handling fields a particular level, the planner groups fields by field name and parent type. In the case above, it treats both occurrences of `f` together, because they have the same parent type `Z`. However, when treating that group, the planner incorrectly ignores the fact that while the parent types are the same, the scope are not fully similar, and it only handles the 1st occurrence of the field. As a result, the generated plan ends up only fetching the first occurrence, which is incorrect (concretely, the gateway never return `Y` objects while it should). This commit fixes the problem by changing the way fields are grouped. Instead of being grouped just by parent type, they are grouped by their scope. So, in the example above, both occurrences of `f` are treated separately. Fixes: apollographql#396
Fix missing fields due to loss of specific scope (fixes #396)
The fix for this was released in |
The 'should preserve type conditions for value types' test had been added in the fix for #396: that fix was primarily ensure that we did not elimiate type condition, even when they not strictly useful to the rest of the selection, _if_ they have directives we need to preserve. But that particular test was actually testing the case where the type condition has no directives and is thus, strictly speaking, useless, and the new query planner now optimize that case "properly". Note that the next test, 'should preserve directives on inline fragments even if the fragment is otherwise useless', test the more interesting where we do want to preserve a type condition due to a directive, and this test is (still) properly handled.
Consider the following query, against the federation demo service:
Apollo gateway generates an incorrect query plan: it should simply pass on an equivalent query to the
products
service, but in fact it entirely omits asking forprice
onFurniture
, and only asks for it onBook
.Test case to reproduce this on master
Test output excerpt:
The text was updated successfully, but these errors were encountered: