diff --git a/.changeset/smart-needles-breathe.md b/.changeset/smart-needles-breathe.md new file mode 100644 index 000000000..66fdcdd7d --- /dev/null +++ b/.changeset/smart-needles-breathe.md @@ -0,0 +1,5 @@ +--- +"@apollo/query-planner": patch +--- + +Switched plan count from `Number` to a `BigInt`. diff --git a/query-planner-js/src/buildPlan.ts b/query-planner-js/src/buildPlan.ts index 6a27faaa1..bf0e0e961 100644 --- a/query-planner-js/src/buildPlan.ts +++ b/query-planner-js/src/buildPlan.ts @@ -665,7 +665,7 @@ class QueryPlanningTraversal { const maxPlansToCompute = this.parameters.config.debug.maxEvaluatedPlans; while (planCount > maxPlansToCompute && firstBranch.length > 1) { // we remove the right-most option of the first branch, and them move that branch to it's new place. - const prevSize = firstBranch.length; + const prevSize = BigInt(firstBranch.length); firstBranch.pop(); planCount -= planCount / prevSize; this.reorderFirstBranch(); @@ -678,7 +678,7 @@ class QueryPlanningTraversal { // Note that if `!this.isTopLevel`, then this means we're resolving a sub-plan for an edge condition, and we // don't want to count those as "evaluated plans". if (this.parameters.statistics && this.isTopLevel) { - this.parameters.statistics.evaluatedPlanCount += planCount; + this.parameters.statistics.evaluatedPlanCount += Number(planCount); } debug.log(() => `All branches:${this.closedBranches.map((opts, i) => `\n${i}:${opts.map((opt => `\n - ${closedPathToString(opt)}`))}`)}`); @@ -3596,16 +3596,16 @@ function mapOptionsToSelections( return selectionSet.selectionsInReverseOrder().map(node => [node, options]); } -function possiblePlans(closedBranches: ClosedBranch[]): number { - let totalCombinations = 1; +function possiblePlans(closedBranches: ClosedBranch[]): bigint { + let totalCombinations = BigInt(1); for (let i = 0; i < closedBranches.length; ++i){ - const eltSize = closedBranches[i].length; - if (eltSize === 0) { + const eltSize = BigInt(closedBranches[i].length); + if (eltSize === BigInt(0)) { // This would correspond to not being to find *any* path for a particular queried field, which means we have no plan // for the overall query. Now, this shouldn't happen in practice if composition validation has been run successfully // (and is not buggy), since the goal of composition validation is exactly to ensure we can never run into this path. // In any case, we will throw later if that happens, but let's just return the proper result here, which is no plan at all. - return 0; + return BigInt(0); } totalCombinations *= eltSize; }