@apollo/query-planner
Advanced tools
Comparing version 2.0.0-alpha.4 to 2.0.0-alpha.5
@@ -436,7 +436,14 @@ "use strict"; | ||
(0, federation_internals_1.assert)(!toMerge.isTopLevel, () => `Shouldn't merge top level group ${toMerge} into ${this}`); | ||
const selectionSet = (0, federation_internals_1.selectionSetOfPath)(mergePath, endOfPathSet => { | ||
const selectionSet = (0, federation_internals_1.selectionSetOfPath)(mergePath, (endOfPathSet) => { | ||
(0, federation_internals_1.assert)(endOfPathSet, () => `Merge path ${mergePath} ends on a non-selectable type`); | ||
for (const typeCastSel of toMerge.selection.selections()) { | ||
(0, federation_internals_1.assert)(typeCastSel instanceof federation_internals_1.FragmentSelection, () => `Unexpected field selection ${typeCastSel} at top-level of ${toMerge} selection.`); | ||
endOfPathSet.mergeIn(typeCastSel.selectionSet); | ||
const entityType = typeCastSel.element().typeCondition; | ||
(0, federation_internals_1.assert)(entityType, () => `Unexpected fragment _without_ condition at start of ${toMerge}`); | ||
if ((0, federation_internals_1.sameType)(endOfPathSet.parentType, entityType)) { | ||
endOfPathSet.mergeIn(typeCastSel.selectionSet); | ||
} | ||
else { | ||
endOfPathSet.add(typeCastSel); | ||
} | ||
} | ||
@@ -892,2 +899,9 @@ }); | ||
} | ||
function extractPathInParentForKeyFetch(type, path) { | ||
var _a; | ||
const lastElement = path[path.length - 1]; | ||
return (lastElement && lastElement.kind === 'FragmentElement' && ((_a = lastElement.typeCondition) === null || _a === void 0 ? void 0 : _a.name) === type.name) | ||
? path.slice(0, path.length - 1) | ||
: path; | ||
} | ||
function computeGroupsForTree(dependencyGraph, pathTree, startGroup, initialMergeAt = [], initialPath = []) { | ||
@@ -909,6 +923,7 @@ const stack = [[pathTree, startGroup, initialMergeAt, initialPath]]; | ||
const groupsForConditions = computeGroupsForTree(dependencyGraph, conditions, group, mergeAt, path); | ||
const newGroup = dependencyGraph.getOrCreateKeyFetchGroup(edge.tail.source, mergeAt, group, path, groupsForConditions); | ||
const type = edge.tail.type; | ||
const pathInParent = extractPathInParentForKeyFetch(type, path); | ||
const newGroup = dependencyGraph.getOrCreateKeyFetchGroup(edge.tail.source, mergeAt, group, pathInParent, groupsForConditions); | ||
createdGroups.push(newGroup); | ||
newGroup.addDependencyOn(groupsForConditions); | ||
const type = edge.tail.type; | ||
const inputSelections = new federation_internals_1.SelectionSet(type); | ||
@@ -1035,3 +1050,2 @@ inputSelections.add(new federation_internals_1.FieldSelection(new federation_internals_1.Field(type.typenameField()))); | ||
const [inputs, newPath] = inputsForRequire(dependencyGraph.federatedQueryGraph, entityType, edge); | ||
debug.log(`Trying to add ${inputs} to ${newGroup}`); | ||
newGroup.addInputs(inputs); | ||
@@ -1038,0 +1052,0 @@ return [newGroup, mergeAt, newPath]; |
{ | ||
"name": "@apollo/query-planner", | ||
"version": "2.0.0-alpha.4", | ||
"version": "2.0.0-alpha.5", | ||
"description": "Apollo Query Planner", | ||
@@ -28,4 +28,4 @@ "author": "Apollo <packages@apollographql.com>", | ||
"dependencies": { | ||
"@apollo/federation-internals": "^2.0.0-alpha.4", | ||
"@apollo/query-graphs": "^2.0.0-alpha.4", | ||
"@apollo/federation-internals": "^2.0.0-alpha.5", | ||
"@apollo/query-graphs": "^2.0.0-alpha.5", | ||
"chalk": "^4.1.0", | ||
@@ -36,5 +36,5 @@ "deep-equal": "^2.0.5", | ||
"peerDependencies": { | ||
"graphql": "^15.7.0 || ^16.0.0" | ||
"graphql": "^16.0.0" | ||
}, | ||
"gitHead": "c32794a48598bac2e2372c23a2ea74ae187cce85" | ||
"gitHead": "efb50aa3d3742d2fed8c841569651b2b7b729f2f" | ||
} |
@@ -948,2 +948,119 @@ import { astSerializer, queryPlanSerializer, QueryPlanner } from '@apollo/query-planner'; | ||
describe('@requires', () => { | ||
it('handles multiple requires within the same entity fetch', () => { | ||
const subgraph1 = { | ||
name: 'Subgraph1', | ||
typeDefs: gql` | ||
type Query { | ||
is: [I!]! | ||
} | ||
interface I { | ||
id: ID! | ||
f: Int | ||
g: Int | ||
} | ||
type T1 implements I { | ||
id: ID! | ||
f: Int | ||
g: Int | ||
} | ||
type T2 implements I @key(fields: "id") { | ||
id: ID! | ||
f: Int! | ||
g: Int @external | ||
} | ||
type T3 implements I @key(fields: "id") { | ||
id: ID! | ||
f: Int | ||
g: Int @external | ||
} | ||
` | ||
} | ||
const subgraph2 = { | ||
name: 'Subgraph2', | ||
typeDefs: gql` | ||
type T2 @key(fields: "id") { | ||
id: ID! | ||
f: Int! @external | ||
g: Int @requires(fields: "f") | ||
} | ||
type T3 @key(fields: "id") { | ||
id: ID! | ||
f: Int @external | ||
g: Int @requires(fields: "f") | ||
} | ||
` | ||
} | ||
const [api, queryPlanner] = composeAndCreatePlanner(subgraph1, subgraph2); | ||
const operation = operationFromDocument(api, gql` | ||
{ | ||
is { | ||
g | ||
} | ||
} | ||
`); | ||
const plan = queryPlanner.buildQueryPlan(operation); | ||
// The main goal of this test is to show that the 2 @requires for `f` gets handled seemlessly | ||
// into the same fetch group. | ||
expect(plan).toMatchInlineSnapshot(` | ||
QueryPlan { | ||
Sequence { | ||
Fetch(service: "Subgraph1") { | ||
{ | ||
is { | ||
__typename | ||
... on T1 { | ||
g | ||
} | ||
... on T2 { | ||
__typename | ||
id | ||
f | ||
} | ||
... on T3 { | ||
__typename | ||
id | ||
f | ||
} | ||
} | ||
} | ||
}, | ||
Flatten(path: "is.@") { | ||
Fetch(service: "Subgraph2") { | ||
{ | ||
... on T2 { | ||
__typename | ||
id | ||
f | ||
} | ||
... on T3 { | ||
__typename | ||
id | ||
f | ||
} | ||
} => | ||
{ | ||
... on T2 { | ||
g | ||
} | ||
... on T3 { | ||
g | ||
} | ||
} | ||
}, | ||
}, | ||
}, | ||
} | ||
`); | ||
}) | ||
}); | ||
test('Correctly handle case where there is too many plans to consider', () => { | ||
@@ -950,0 +1067,0 @@ // Creating realistic examples where there is too many plan to consider is not trivial, but creating unrealistic examples |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
405042
5064