diff --git a/.changeset/cuddly-badgers-sit.md b/.changeset/cuddly-badgers-sit.md new file mode 100644 index 000000000..c9880a281 --- /dev/null +++ b/.changeset/cuddly-badgers-sit.md @@ -0,0 +1,6 @@ +--- +"@apollo/gateway": patch +"@apollo/query-graphs": patch +--- + +Avoid type explosion for inline fragments where the type condition is an interface that implements the parent type. diff --git a/gateway-js/src/__tests__/executeQueryPlan.test.ts b/gateway-js/src/__tests__/executeQueryPlan.test.ts index 160f4cf0e..c9e585f2f 100644 --- a/gateway-js/src/__tests__/executeQueryPlan.test.ts +++ b/gateway-js/src/__tests__/executeQueryPlan.test.ts @@ -2300,22 +2300,14 @@ describe('executeQueryPlan', () => { queryPlan = buildPlan(operation, queryPlanner); - // TODO: we're actually type-exploding in this case because currently, as soon as we need to type-explode, we do - // so into all the runtime types, while here it could make sense to only type-explode into the direct sub-types= - // (the sub-interfaces). We should fix this (but it's only sub-optimal, not incorrect). expect(queryPlan).toMatchInlineSnapshot(` QueryPlan { Fetch(service: "S1") { { allValues { __typename - ... on T1 { - a - } - ... on T2 { - a - } - ... on T4 { + ... on SubInterface1 { + __typename a } } diff --git a/query-graphs-js/src/querygraph.ts b/query-graphs-js/src/querygraph.ts index 1d98286c1..d2f738d40 100644 --- a/query-graphs-js/src/querygraph.ts +++ b/query-graphs-js/src/querygraph.ts @@ -1611,12 +1611,6 @@ class GraphBuilderFromSchema extends GraphBuilder { for (let j = i; j < abstractTypesWithTheirRuntimeTypes.length; j++) { const t2 = abstractTypesWithTheirRuntimeTypes[j]; - // We ignore the pair if both are interfaces and one implements the other. We'll already have appropriate - // edges if that's the case. - if (isInterfaceType(t1.type) && isInterfaceType(t2.type) && (t1.type.implementsInterface(t2.type) || t2.type.implementsInterface(t1.type))) { - continue; - } - let addT1ToT2 = false; let addT2ToT1 = false; if (t1.type === t2.type) {