diff options
Diffstat (limited to 'src/mongo/dbtests/plan_ranking.cpp')
-rw-r--r-- | src/mongo/dbtests/plan_ranking.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/mongo/dbtests/plan_ranking.cpp b/src/mongo/dbtests/plan_ranking.cpp index 5d15a00fd45..1be5d0ad9d0 100644 --- a/src/mongo/dbtests/plan_ranking.cpp +++ b/src/mongo/dbtests/plan_ranking.cpp @@ -700,6 +700,45 @@ namespace PlanRankingTests { } }; + /** + * When no other information is available, prefer solutions without + * a blocking sort stage. + */ + class PlanRankingAvoidBlockingSort : public PlanRankingTestBase { + public: + void run() { + static const int N = 10000; + + for (int i = 0; i < N; ++i) { + insert(BSON("a" << 1 << "d" << i)); + } + + // The index {d: 1, e: 1} provides the desired sort order, + // while index {a: 1, b: 1} can be used to answer the + // query predicate, but does not provide the sort. + addIndex(BSON("a" << 1 << "b" << 1)); + addIndex(BSON("d" << 1 << "e" << 1)); + + // Query: find({a: 1}).sort({d: 1}) + CanonicalQuery* cq; + ASSERT(CanonicalQuery::canonicalize(ns, + BSON("a" << 1), + BSON("d" << 1), // sort + BSONObj(), // projection + &cq).isOK()); + ASSERT(NULL != cq); + + // No results will be returned during the trial period, + // so we expect to choose {d: 1, e: 1}, as it allows us + // to avoid the sort stage. + QuerySolution* soln = pickBestPlan(cq); + ASSERT(QueryPlannerTestLib::solutionMatches( + "{fetch: {filter: {a:1}, node: " + "{ixscan: {filter: null, pattern: {d:1,e:1}}}}}", + soln->root.get())); + } + }; + class All : public Suite { public: All() : Suite( "query_plan_ranking" ) {} @@ -718,6 +757,7 @@ namespace PlanRankingTests { add<PlanRankingNonCoveredIxisectFetchesLess>(); add<PlanRankingIxisectHitsEOFFirst>(); add<PlanRankingChooseBetweenIxisectPlans>(); + add<PlanRankingAvoidBlockingSort>(); } } planRankingAll; |