summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/explain.cpp20
-rw-r--r--src/mongo/dbtests/queryoptimizercursortests.cpp43
2 files changed, 51 insertions, 12 deletions
diff --git a/src/mongo/db/explain.cpp b/src/mongo/db/explain.cpp
index 89a7f0bef5d..ecfa182f85e 100644
--- a/src/mongo/db/explain.cpp
+++ b/src/mongo/db/explain.cpp
@@ -170,22 +170,18 @@ namespace mongo {
}
}
// Return a plan with the highest match count.
- // TODO simplify
- long long maxN = 0;
+ long long maxN = -1;
+ shared_ptr<const ExplainPlanInfo> ret;
for( list<shared_ptr<const ExplainPlanInfo> >::const_iterator i = _plans.begin();
i != _plans.end(); ++i ) {
- if ( (*i)->n() > maxN ) {
- maxN = (*i)->n();
+ long long n = ( *i )->n();
+ if ( n > maxN ) {
+ maxN = n;
+ ret = *i;
}
}
- for( list<shared_ptr<const ExplainPlanInfo> >::const_iterator i = _plans.begin();
- i != _plans.end(); ++i ) {
- if ( (*i)->n() == maxN ) {
- return **i;
- }
- }
- verify( 16076, false );
- return *(new ExplainPlanInfo());
+ verify( 16076, ret );
+ return *ret;
}
void ExplainQueryInfo::noteIterate( bool match, bool loadedObject, bool chunkSkip ) {
diff --git a/src/mongo/dbtests/queryoptimizercursortests.cpp b/src/mongo/dbtests/queryoptimizercursortests.cpp
index 905f1172fa1..c083a863580 100644
--- a/src/mongo/dbtests/queryoptimizercursortests.cpp
+++ b/src/mongo/dbtests/queryoptimizercursortests.cpp
@@ -3891,6 +3891,48 @@ namespace QueryOptimizerCursorTests {
ASSERT( clause1[ "indexOnly" ].Bool() );
}
};
+
+ /**
+ * Check that the plan with the most matches is reported at the top of the explain output
+ * in the absence of a done or picked plan.
+ */
+ class VirtualPickedPlan : public Base {
+ public:
+ void run() {
+ dblock lk;
+ Client::Context ctx( ns() );
+
+ _cli.ensureIndex( ns(), BSON( "a" << 1 ) );
+ _cli.ensureIndex( ns(), BSON( "b" << 1 ) );
+ _cli.ensureIndex( ns(), BSON( "c" << 1 ) );
+
+ shared_ptr<Cursor> aCursor
+ ( NamespaceDetailsTransient::getCursor( ns(), BSON( "a" << 1 ) ) );
+ shared_ptr<Cursor> bCursor
+ ( NamespaceDetailsTransient::getCursor( ns(), BSON( "b" << 1 ) ) );
+ shared_ptr<Cursor> cCursor
+ ( NamespaceDetailsTransient::getCursor( ns(), BSON( "c" << 1 ) ) );
+
+ shared_ptr<ExplainPlanInfo> aPlan( new ExplainPlanInfo() );
+ aPlan->notePlan( *aCursor, false, false );
+ shared_ptr<ExplainPlanInfo> bPlan( new ExplainPlanInfo() );
+ bPlan->notePlan( *bCursor, false, false );
+ shared_ptr<ExplainPlanInfo> cPlan( new ExplainPlanInfo() );
+ cPlan->notePlan( *cCursor, false, false );
+
+ aPlan->noteIterate( true, false, *aCursor ); // one match a
+ bPlan->noteIterate( true, false, *bCursor ); // two matches b
+ bPlan->noteIterate( true, false, *bCursor );
+ cPlan->noteIterate( true, false, *cCursor ); // one match c
+
+ shared_ptr<ExplainClauseInfo> clause( new ExplainClauseInfo() );
+ clause->addPlanInfo( aPlan );
+ clause->addPlanInfo( bPlan );
+ clause->addPlanInfo( cPlan );
+
+ ASSERT_EQUALS( "BtreeCursor b_1", clause->bson()[ "cursor" ].String() );
+ }
+ };
// test takeover w/ mixed plan clause ? necessary?
@@ -4046,6 +4088,7 @@ namespace QueryOptimizerCursorTests {
add<Explain::NChunkSkipsTakeover>();
add<Explain::CoveredIndex>();
add<Explain::CoveredIndexTakeover>();
+ add<Explain::VirtualPickedPlan>();
}
} myall;