diff --git a/db/queryoptimizer.cpp b/db/queryoptimizer.cpp index 3fc32204691..1f3f4b59d1f 100644 --- a/db/queryoptimizer.cpp +++ b/db/queryoptimizer.cpp @@ -600,11 +600,9 @@ namespace mongo { if ( !_or ) { auto_ptr< FieldRangeSet > frs( new FieldRangeSet( ns, _query ) ); _currentQps.reset( new QueryPlanSet( ns, frs, _query, order, hint, honorRecordedPlan, min, max ) ); - _n = 1; // only one run } else { BSONElement e = _query.getField( "$or" ); massert( 13268, "invalid $or spec", e.type() == Array && e.embeddedObject().nFields() > 0 ); - _n = e.embeddedObject().nFields(); } } @@ -614,11 +612,9 @@ namespace mongo { ++_i; return _currentQps->runOp( op ); } - if ( _i != 0 ) { - _fros.popOrClause(); - } ++_i; auto_ptr< FieldRangeSet > frs( _fros.topFrs() ); + _fros.popOrClause(); _currentQps.reset( new QueryPlanSet( _ns, frs, _query, BSONObj(), 0, _honorRecordedPlan ) ); shared_ptr< QueryOp > ret( _currentQps->runOp( op ) ); return ret; diff --git a/db/queryoptimizer.h b/db/queryoptimizer.h index 9964fbd7767..d2476808bb0 100644 --- a/db/queryoptimizer.h +++ b/db/queryoptimizer.h @@ -263,7 +263,7 @@ namespace mongo { shared_ptr< T > runOpOnce( T &op ) { return dynamic_pointer_cast< T >( runOpOnce( static_cast< QueryOp& >( op ) ) ); } - bool mayRunMore() const { return _i < _n; } + bool mayRunMore() const { return _or ? !_fros.orFinished() : _i == 0; } BSONObj oldExplain() const { assertNotOr(); return _currentQps->explain(); } // just report this when only one query op bool usingPrerecordedPlan() const { @@ -281,7 +281,6 @@ namespace mongo { FieldRangeOrSet _fros; auto_ptr< QueryPlanSet > _currentQps; int _i; - int _n; bool _honorRecordedPlan; bool _bestGuessOnly; }; diff --git a/jstests/or6.js b/jstests/or6.js index 3a0369ebbdb..00c94a71cd3 100644 --- a/jstests/or6.js +++ b/jstests/or6.js @@ -6,4 +6,11 @@ t.ensureIndex( {a:1} ); assert.eq.automsg( "2", "t.find( {$or:[{a:{$gt:2}},{a:{$gt:0}}]} ).explain().clauses[ 1 ].indexBounds[ 0 ][ 1 ].a" ); assert.eq.automsg( "2", "t.find( {$or:[{a:{$lt:2}},{a:{$lt:4}}]} ).explain().clauses[ 1 ].indexBounds[ 0 ][ 0 ].a" ); -printjson( t.find( {$or:[{a:{$lt:2}},{a:{$lt:4}}]} ).explain() ); \ No newline at end of file +assert.eq.automsg( "2", "t.find( {$or:[{a:{$gt:2,$lt:10}},{a:{$gt:0,$lt:5}}]} ).explain().clauses[ 1 ].indexBounds[ 0 ][ 1 ].a" ); +assert.eq.automsg( "0", "t.find( {$or:[{a:{$gt:2,$lt:10}},{a:{$gt:0,$lt:15}}]} ).explain().clauses[ 1 ].indexBounds[ 0 ][ 0 ].a" ); +assert.eq.automsg( "15", "t.find( {$or:[{a:{$gt:2,$lt:10}},{a:{$gt:0,$lt:15}}]} ).explain().clauses[ 1 ].indexBounds[ 0 ][ 1 ].a" ); + +// no separate clauses +assert.eq.automsg( "null", "t.find( {$or:[{a:{$gt:2,$lt:10}},{a:{$gt:3,$lt:5}}]} ).explain().clauses" ); + +assert.eq.automsg( "20", "t.find( {$or:[{a:{$gt:2,$lt:10}},{a:{$gt:3,$lt:5}},{a:{$gt:20}}]} ).explain().clauses[ 1 ].indexBounds[ 0 ][ 0 ].a" ); \ No newline at end of file