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 assertion errors when querying types with no common supertypes at… #2467

Merged
merged 1 commit into from
Mar 15, 2023

Conversation

pcmanus
Copy link
Contributor

@pcmanus pcmanus commented Mar 15, 2023

… the same path

Fetches input selections used to be based on the queried subgraph schema. However, those selections truly applies to the in-memory data maintained by the gateway/router, so the supergraph. This used to not matter (all input selection did correctly applied to the subgraph schema), but @interfaceObject made it so that some input selections could be invalid for the subgraph. Typically, a fetch that queries a subgraph with an @interfaceObject may look like:

Fetch(service: 'A') {
  {
    ... on Book {
      id
    }
  } => {
    ... on Product {
      <some fields>
    }
  }
}

where Book is a concrete implementation of Product but unknown to subgraph A.

However, basing the input selections on the supergraph schema means having the parent type, in the supergraph, for those selections, and because some fetches can query multiple different entities, this is not trivial.

The initial code for @interfaceObject make the (incorrect) assumption that, when a fetch does query multiple types, then we could always find a common supertype for all those types, and so was using that type as parent type.

Unfortunately, this isn't always true (see test in this PR, which uses a union type with types having a field with the same name but different (and unrelated) types).

So in pratice, fetch inputs cannot always have a common parent type. This patch thus changes the fetch inputs to be a map of type to selection sets instead of a single selection set.

Note that it does mean that the requires field of a FetchGroup is not a true valid "single" selection for the supergraph (or any subgraph for that matter), but it is more of a "fun fact" since the execution never relied on this anyway.

Fixes #2466

… the same path

Fetches input selections used to be based on the queried subgraph
schema. However, those selections truly applies to the in-memory data
maintained by the gateway/router, so the supergraph. This used to
not matter (all input selection did correctly applied to the subgraph
schema), but `@interfaceObject` made it so that some input selections
could be invalid for the subgraph. Typically, a fetch that queries a
subgraph with an `@interfaceObject` may look like:
```
Fetch(service: 'A') {
  {
    ... on Book {
      id
    }
  } => {
    ... on Product {
      <some fields>
    }
  }
}
```
where `Book` is a concrete implementation of `Product` but unknown to
subgraph `A`.

However, basing the input selections on the supergraph schema means
having the parent type, in the supergraph, for those selections, and
because some fetches can query multiple different entities, this is
not trivial.

The initial code for `@interfaceObject` make the (incorrect) assumption
that, when a fetch does query multiple types, then we could always find
a common supertype for all those types, and so was using that type as
parent type.

Unfortunately, this isn't always true (see test in this PR, which uses
a union type with types having a field with the same name but different
(and unrelated) types).

So in pratice, fetch inputs cannot always have a common parent type.
This patch thus changes the fetch inputs to be a map of type to
selection sets instead of a single selection set.

Note that it does mean that the `requires` field of a `FetchGroup` is
not a true valid "single" selection for the supergraph (or any subgraph
for that matter), but it is more of a "fun fact" since the execution
never relied on this anyway.

Fixes apollographql#2466
@netlify
Copy link

netlify bot commented Mar 15, 2023

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

Visit the deploys page to approve it

Name Link
🔨 Latest commit 2093d61

@changeset-bot
Copy link

changeset-bot bot commented Mar 15, 2023

🦋 Changeset detected

Latest commit: 2093d61

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 7 packages
Name Type
@apollo/query-planner Patch
@apollo/gateway Patch
@apollo/federation-internals Patch
@apollo/composition Patch
@apollo/query-graphs Patch
@apollo/subgraph Patch
apollo-federation-integration-testsuite Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codesandbox-ci
Copy link

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 pcmanus merged commit 09382e7 into apollographql:main Mar 15, 2023
This was referenced Mar 15, 2023
@clenfest clenfest added this to the 2.4 milestone Mar 16, 2023
pcmanus pushed a commit that referenced this pull request May 16, 2023
… the same path (#2467)

Fetches input selections used to be based on the queried subgraph
schema. However, those selections truly applies to the in-memory data
maintained by the gateway/router, so the supergraph. This used to
not matter (all input selection did correctly applied to the subgraph
schema), but `@interfaceObject` made it so that some input selections
could be invalid for the subgraph. Typically, a fetch that queries a
subgraph with an `@interfaceObject` may look like:
```
Fetch(service: 'A') {
  {
    ... on Book {
      id
    }
  } => {
    ... on Product {
      <some fields>
    }
  }
}
```
where `Book` is a concrete implementation of `Product` but unknown to
subgraph `A`.

However, basing the input selections on the supergraph schema means
having the parent type, in the supergraph, for those selections, and
because some fetches can query multiple different entities, this is
not trivial.

The initial code for `@interfaceObject` make the (incorrect) assumption
that, when a fetch does query multiple types, then we could always find
a common supertype for all those types, and so was using that type as
parent type.

Unfortunately, this isn't always true (see test in this PR, which uses
a union type with types having a field with the same name but different
(and unrelated) types).

So in pratice, fetch inputs cannot always have a common parent type.
This patch thus changes the fetch inputs to be a map of type to
selection sets instead of a single selection set.

Note that it does mean that the `requires` field of a `FetchGroup` is
not a true valid "single" selection for the supergraph (or any subgraph
for that matter), but it is more of a "fun fact" since the execution
never relied on this anyway.

Fixes #2466
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.

Query planner fails with message: **non common supertype**
3 participants