Skip to content
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

Fix issue with @requires and conditional queries (@include and @skip) #1835

Merged
merged 3 commits into from
May 17, 2022

Conversation

pcmanus
Copy link
Contributor

@pcmanus pcmanus commented May 6, 2022

Writing a few unit test around the interaction @require and @include/@skip, I noticed 2 issues/inefficiencies. See the commits for more details.

@netlify
Copy link

netlify bot commented May 6, 2022

👷 Deploy request for apollo-federation-docs pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit 1428453

@codesandbox-ci
Copy link

codesandbox-ci bot commented May 9, 2022

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

@pcmanus
Copy link
Contributor Author

pcmanus commented May 9, 2022

Added a 3rd commit to this PR as a 3rd issue around @requires and @skip/@include was found. That later issue is due to multiple @skip and/or @include being involved and actually leads to inefficient plans where extra obviously-useless fetches are kept instead of being optimised out.

Copy link
Contributor

@benweatherman benweatherman left a comment

Choose a reason for hiding this comment

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

🐐

Sylvain Lebresne added 3 commits May 17, 2022 11:16
A plans are built, the query planner has a notion of context
(`PathContext` in the), which currently is only use to remember which
`@include` or `@skip` are in effect at any point of the query planning.

That context wasn't always properly taken into account when handling
the inputs for a `@require`. Note that as for the current code,
the consequence was extremely minor due to the fact that the current
query plan format "loses" directives like `@include` and `@skip`
in the fetch inputs and in practice it means that the only consequence
of this was a fetch in the plan may have inputs looking like:
```
{
  ... on T {
    __typename
    id
  }
  ... on T {
    a
  }
}
```
which is valid but is a bit confusing as to why both parts aren't
merged (and the underlying reason what that one of the branch had
a `@include` condition under hood while one didn't and so they
weren't merge).

In any case, while the consequence is very minor, the handling was
still somewhat incorrect. In particular, we should (imo) fix the
fact that `@include` and `@skip` are not in the query plan inputs,
and once we do the fix of this commit will become more important.
If a field has a `@require`, but that field is only conditionally
requested in the query (through `@include` or `@skip`), then the
requirement for this field should also ideally only be queried
conditionally, but this wasn't always the case (due to a method
that merges fetch-group ignoring some directives).
The code that recognize (and optimize accordindly) when a `@require`
condition is taken _just after_ a key edge (which is the most common
case in practice) was mistakenly assuming that the selection set
"just after a key edge" was only starting by a single fragment.
In practice, when multiple conditions (`@skip`/`@include`) are
involved, all those conditions are preserved and may be layed out
on multiple conditions. That is, after a key edge, the selection
set may look like:
```graphql
... on EntityType @Skip(if: $c1) {
  ... on EntityType @include(if: $c2) {
    <rest of the selection>
  }
}
```
In that case, the wrong part of the code was taken and this
resulted in unoptimized query plans, ones having useless fetches.

The commit fixes the condition, and ensure that now that the proper
optimizations do apply, we streamline the created result sets by
avoiding repeating conditions multiple times.
@pcmanus pcmanus merged commit f8f32cf into apollographql:main May 17, 2022
@benweatherman benweatherman mentioned this pull request May 20, 2022
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.

2 participants