@@ -2307,6 +2307,68 @@ TEST_F(QueryPlannerTest, ContainedOrPushdownIndexedExpr) {
2307
2307
assertSolutionExists (" {cscan: {dir: 1}}}}" );
2308
2308
}
2309
2309
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
+ }
2310
2372
2311
2373
} // namespace
2312
2374
} // namespace mongo
0 commit comments