@@ -2307,6 +2307,68 @@ TEST_F(QueryPlannerTest, ContainedOrPushdownIndexedExpr) {
23072307 assertSolutionExists (" {cscan: {dir: 1}}}}" );
23082308}
23092309
2310+ // SERVER-41872 fixed a case where variable "choice" ordering in the PlanEnumerator memo could lead
2311+ // to different sets of solutions generated for the same input. This would occur in the case where
2312+ // we only enumerate a subset of possible plans due to reaching internal limits and enumerate plans
2313+ // in a non-stable order. With the fix for SERVER-41872, PlanEnumerator ordering is stable and
2314+ // expected to always return the same set of solutions for a given input.
2315+ TEST_F (QueryPlannerTest, SolutionSetStableWhenOrEnumerationLimitIsReached) {
2316+ params.options = QueryPlannerParams::NO_TABLE_SCAN;
2317+ addIndex (BSON (" d" << 1 ));
2318+ addIndex (BSON (" e" << 1 ));
2319+ addIndex (BSON (" f" << 1 ));
2320+ addIndex (BSON (" f" << 1 << " y" << 1 ));
2321+ addIndex (BSON (" a" << 1 ));
2322+ addIndex (BSON (" b" << 1 ));
2323+ addIndex (BSON (" c" << 1 ));
2324+ addIndex (BSON (" c" << 1 << " x" << 1 ));
2325+
2326+ runQueryAsCommand (
2327+ fromjson (" {find: 'testns', filter: {$or: [{a: 1, b: 1, c: 1}, {d: 1, e: 1, f: 1}]}}" ));
2328+
2329+ assertNumSolutions (10U );
2330+
2331+ assertSolutionExists (
2332+ " {or: {nodes: [{fetch: {filter: {b: {$eq: 1}, c: {$eq: 1} }, node: {ixscan: {pattern: {a: "
2333+ " 1}}}}}, {fetch: {filter: {e: {$eq: 1}, f: {$eq: 1} }, node: {ixscan: {pattern: {d: "
2334+ " 1}}}}}]}}" );
2335+ assertSolutionExists (
2336+ " {or: {nodes: [{fetch: {filter: {a: {$eq: 1}, c: {$eq: 1} }, node: {ixscan: {pattern: {b: "
2337+ " 1}}}}}, {fetch: {filter: {e: {$eq: 1}, f: {$eq: 1} }, node: {ixscan: {pattern: {d: "
2338+ " 1}}}}}]}}" );
2339+ assertSolutionExists (
2340+ " {or: {nodes: [{fetch: {filter: {a: {$eq: 1}, b: {$eq: 1} }, node: {ixscan: {pattern: {c: "
2341+ " 1}}}}}, {fetch: {filter: {e: {$eq: 1}, f: {$eq: 1} }, node: {ixscan: {pattern: {d: "
2342+ " 1}}}}}]}}" );
2343+ assertSolutionExists (
2344+ " {or: {nodes: [{fetch: {filter: {a: {$eq: 1}, b: {$eq: 1} }, node: {ixscan: {pattern: {c: "
2345+ " 1, x: 1}}}}}, {fetch: {filter: {e: {$eq: 1}, f: {$eq: 1} }, node: {ixscan: {pattern: {d: "
2346+ " 1}}}}}]}}" );
2347+ assertSolutionExists (
2348+ " {or: {nodes: [{fetch: {filter: {b: {$eq: 1}, c: {$eq: 1} }, node: {ixscan: {pattern: {a: "
2349+ " 1}}}}}, {fetch: {filter: {d: {$eq: 1}, f: {$eq: 1} }, node: {ixscan: {pattern: {e: "
2350+ " 1}}}}}]}}" );
2351+ assertSolutionExists (
2352+ " {or: {nodes: [{fetch: {filter: {a: {$eq: 1}, c: {$eq: 1} }, node: {ixscan: {pattern: {b: "
2353+ " 1}}}}}, {fetch: {filter: {d: {$eq: 1}, f: {$eq: 1} }, node: {ixscan: {pattern: {e: "
2354+ " 1}}}}}]}}" );
2355+ assertSolutionExists (
2356+ " {or: {nodes: [{fetch: {filter: {a: {$eq: 1}, b: {$eq: 1} }, node: {ixscan: {pattern: {c: "
2357+ " 1}}}}}, {fetch: {filter: {d: {$eq: 1}, f: {$eq: 1} }, node: {ixscan: {pattern: {e: "
2358+ " 1}}}}}]}}" );
2359+ assertSolutionExists (
2360+ " {or: {nodes: [{fetch: {filter: {a: {$eq: 1}, b: {$eq: 1} }, node: {ixscan: {pattern: {c: "
2361+ " 1, x: 1}}}}}, {fetch: {filter: {d: {$eq: 1}, f: {$eq: 1} }, node: {ixscan: {pattern: {e: "
2362+ " 1}}}}}]}}" );
2363+ assertSolutionExists (
2364+ " {or: {nodes: [{fetch: {filter: {b: {$eq: 1}, c: {$eq: 1} }, node: {ixscan: {pattern: {a: "
2365+ " 1}}}}}, {fetch: {filter: {d: {$eq: 1}, e: {$eq: 1} }, node: {ixscan: {pattern: {f: "
2366+ " 1}}}}}]}}" );
2367+ assertSolutionExists (
2368+ " {or: {nodes: [{fetch: {filter: {a: {$eq: 1}, c: {$eq: 1} }, node: {ixscan: {pattern: {b: "
2369+ " 1}}}}}, {fetch: {filter: {d: {$eq: 1}, e: {$eq: 1} }, node: {ixscan: {pattern: {f: "
2370+ " 1}}}}}]}}" );
2371+ }
23102372
23112373} // namespace
23122374} // namespace mongo
0 commit comments