diff --git a/db/queryoptimizer.cpp b/db/queryoptimizer.cpp index c29f9caf02a..24d98f35e76 100644 --- a/db/queryoptimizer.cpp +++ b/db/queryoptimizer.cpp @@ -641,7 +641,8 @@ namespace mongo { _honorRecordedPlan( honorRecordedPlan ), _bestGuessOnly( bestGuessOnly ), _hint( ( hint && !hint->eoo() ) ? hint->wrap() : BSONObj() ), - _mayYield( mayYield ) + _mayYield( mayYield ), + _tableScanned() { if ( !order.isEmpty() || !min.isEmpty() || !max.isEmpty() || !_fros.getSpecial().empty() ) { _or = false; @@ -670,6 +671,9 @@ namespace mongo { BSONElement hintElt = _hint.firstElement(); _currentQps.reset( new QueryPlanSet( _ns, frs, _query, BSONObj(), &hintElt, _honorRecordedPlan, BSONObj(), BSONObj(), _bestGuessOnly, _mayYield ) ); shared_ptr< QueryOp > ret( _currentQps->runOp( op ) ); + if ( ret->qp().willScanTable() ) { + _tableScanned = true; + } _fros.popOrClause(); return ret; } diff --git a/db/queryoptimizer.h b/db/queryoptimizer.h index 55a30b2f98a..6d361e11262 100644 --- a/db/queryoptimizer.h +++ b/db/queryoptimizer.h @@ -55,6 +55,7 @@ namespace mongo { shared_ptr newCursor( const DiskLoc &startLoc = DiskLoc() , int numWanted=0 ) const; shared_ptr newReverseCursor() const; BSONObj indexKey() const; + bool willScanTable() const { return !index_ && fbs_.matchPossible(); } const char *ns() const { return fbs_.ns(); } NamespaceDetails *nsd() const { return d; } BSONObj originalQuery() const { return _originalQuery; } @@ -275,7 +276,7 @@ namespace mongo { shared_ptr< T > runOpOnce( T &op ) { return dynamic_pointer_cast< T >( runOpOnce( static_cast< QueryOp& >( op ) ) ); } - bool mayRunMore() const { return _or ? !_fros.orFinished() : _i == 0; } + bool mayRunMore() const { return _or ? ( !_tableScanned && !_fros.orFinished() ) : _i == 0; } BSONObj oldExplain() const { assertNotOr(); return _currentQps->explain(); } // just report this when only one query op bool usingPrerecordedPlan() const { @@ -298,6 +299,7 @@ namespace mongo { bool _bestGuessOnly; BSONObj _hint; bool _mayYield; + bool _tableScanned; }; class MultiCursor : public Cursor { diff --git a/jstests/or9.js b/jstests/or9.js index 5c03660f1e9..0df215309c4 100644 --- a/jstests/or9.js +++ b/jstests/or9.js @@ -24,7 +24,7 @@ check( 1, 2, { $or: [ { a: { $gt:2,$lte:3 } }, { a: 2 } ] } ); check( 1, 1, { $or: [ { b: { $gte:1,$lte:3 } }, { b: 2 } ] } ); check( 1, 1, { $or: [ { b: { $gte:2,$lte:3 } }, { b: 2 } ] } ); -//check( 1, 2, { $or: [ { b: { $gt:2,$lte:3 } }, { b: 2 } ] } ); +check( 1, 1, { $or: [ { b: { $gt:2,$lte:3 } }, { b: 2 } ] } ); check( 1, 1, { $or: [ { a: { $gte:1,$lte:3 } }, { a: 2, b: 2 } ] } ); check( 1, 2, { $or: [ { a: { $gte:1,$lte:3 }, b:3 }, { a: 2 } ] } );