diff --git a/.changeset/ten-gorillas-boil.md b/.changeset/ten-gorillas-boil.md new file mode 100644 index 000000000..fcecdfa83 --- /dev/null +++ b/.changeset/ten-gorillas-boil.md @@ -0,0 +1,6 @@ +--- +"@apollo/composition": patch +"@apollo/query-graphs": patch +--- + +Fix bug in composition where, when a field's type in a subgraph is a subtype of the field's type in the supergraph, the satisfiability validation spuriously succeeds/errors. diff --git a/composition-js/src/validate.ts b/composition-js/src/validate.ts index a813647ef..b1c552558 100644 --- a/composition-js/src/validate.ts +++ b/composition-js/src/validate.ts @@ -641,6 +641,7 @@ export class ValidationState { for (const pathInfo of this.subgraphPathInfos) { const tailSubgraphName = pathInfo.path.path.tail.source; const tailSubgraphEnumValue = subgraphNameToGraphEnumValue.get(tailSubgraphName); + const tailTypeName = pathInfo.path.path.tail.type.name; const entryKeys = []; const contexts = Array.from(pathInfo.contexts.entries()); contexts.sort((a, b) => a[0].localeCompare(b[0])); @@ -649,7 +650,7 @@ export class ValidationState { entryKeys.push(`${context}=${subgraphEnumValue}.${typeName}`); } subgraphContextKeys.add( - `${tailSubgraphEnumValue}[${entryKeys.join(',')}]` + `${tailSubgraphEnumValue}.${tailTypeName}[${entryKeys.join(',')}]` ); } return subgraphContextKeys; diff --git a/query-graphs-js/src/graphPath.ts b/query-graphs-js/src/graphPath.ts index ba87dc723..e32dbb656 100644 --- a/query-graphs-js/src/graphPath.ts +++ b/query-graphs-js/src/graphPath.ts @@ -1735,6 +1735,15 @@ function advancePathWithDirectTransition( // We can now continue on dealing with the actual field. } + if ( + transition.kind === 'DownCast' + && transition.castedType.name === path.tail.type.name + ) { + // Due to output type covariance, a downcast supergraph transition may be a no-op on the + // subgraph path. In these cases, we effectively ignore the type condition. + return [path]; + } + const options: GraphPath[] = []; const deadEndClosures: UnadvanceableClosure[] = [];