diff options
-rw-r--r-- | db/queryoptimizer.cpp | 23 | ||||
-rw-r--r-- | db/queryoptimizer.h | 9 | ||||
-rw-r--r-- | dbtests/queryoptimizertests.cpp | 110 |
3 files changed, 75 insertions, 67 deletions
diff --git a/db/queryoptimizer.cpp b/db/queryoptimizer.cpp index 13dc63a1791..2d6d7033506 100644 --- a/db/queryoptimizer.cpp +++ b/db/queryoptimizer.cpp @@ -33,11 +33,11 @@ namespace mongo { QueryPlan::QueryPlan( NamespaceDetails *_d, int _idxNo, - const FieldBoundSet &fbs, const BSONObj &order, const IndexDetails *index, const BSONObj &startKey, const BSONObj &endKey ) : + const FieldBoundSet &fbs, const BSONObj &order, const BSONObj &startKey, const BSONObj &endKey ) : d(_d), idxNo(_idxNo), fbs_( fbs ), order_( order ), - index_( index ), + index_( 0 ), optimal_( false ), scanAndOrderRequired_( true ), exactKeyMatch_( false ), @@ -46,14 +46,17 @@ namespace mongo { endKey_( endKey ), endKeyInclusive_( endKey_.isEmpty() ), unhelpful_( false ) { - // full table scan case - if ( !index_ ) { + + if( idxNo >= 0 ) { + index_ = &d->indexes[idxNo]; + } else { + // full table scan case if ( order_.isEmpty() || !strcmp( order_.firstElement().fieldName(), "$natural" ) ) scanAndOrderRequired_ = false; return; } - BSONObj idxKey = index->keyPattern(); + BSONObj idxKey = index_->keyPattern(); BSONObjIterator o( order ); BSONObjIterator k( idxKey ); if ( !o.moreWithEOO() ) @@ -123,7 +126,7 @@ namespace mongo { optimal_ = true; if ( exactIndexedQueryCount == fbs.nNontrivialBounds() && orderFieldsUnindexed.size() == 0 && - exactIndexedQueryCount == index->keyPattern().nFields() && + exactIndexedQueryCount == index_->keyPattern().nFields() && exactIndexedQueryCount == fbs.query().nFields() ) { exactKeyMatch_ = true; } @@ -196,7 +199,7 @@ namespace mongo { massert( errmsg, indexDetailsForRange( fbs_.ns(), errmsg, min_, max_, keyPattern ) ); } NamespaceDetails *d = nsdetails(ns); - plans_.push_back( PlanPtr( new QueryPlan( d, d->idxNo(id), fbs_, order_, &id, min_, max_ ) ) ); + plans_.push_back( PlanPtr( new QueryPlan( d, d->idxNo(id), fbs_, order_, min_, max_ ) ) ); } void QueryPlanSet::init() { @@ -250,7 +253,7 @@ namespace mongo { BSONObj keyPattern; IndexDetails *idx = indexDetailsForRange( ns, errmsg, min_, max_, keyPattern ); massert( errmsg, idx ); - plans_.push_back( PlanPtr( new QueryPlan( d, d->idxNo(*idx), fbs_, order_, idx, min_, max_ ) ) ); + plans_.push_back( PlanPtr( new QueryPlan( d, d->idxNo(*idx), fbs_, order_, min_, max_ ) ) ); return; } @@ -268,7 +271,7 @@ namespace mongo { for (int i = 0; i < d->nIndexes; i++ ) { IndexDetails& ii = d->indexes[i]; if( ii.keyPattern().woCompare(bestIndex) == 0 ) { - plans_.push_back( PlanPtr( new QueryPlan( d, i, fbs_, order_, &ii ) ) ); + plans_.push_back( PlanPtr( new QueryPlan( d, i, fbs_, order_ ) ) ); return; } } @@ -295,7 +298,7 @@ namespace mongo { PlanSet plans; for( int i = 0; i < d->nIndexes; ++i ) { - PlanPtr p( new QueryPlan( d, i, fbs_, order_, &d->indexes[ i ] ) ); + PlanPtr p( new QueryPlan( d, i, fbs_, order_ ) ); if ( p->optimal() ) { addPlan( p, checkFirst ); return; diff --git a/db/queryoptimizer.h b/db/queryoptimizer.h index a43edd6b77a..ceb50ff2404 100644 --- a/db/queryoptimizer.h +++ b/db/queryoptimizer.h @@ -25,15 +25,16 @@ namespace mongo { class IndexDetails; - class QueryPlan { + class QueryPlan : boost::noncopyable { public: - QueryPlan(NamespaceDetails *_d, int _idxNo, + QueryPlan(NamespaceDetails *_d, + int _idxNo, // -1 = no index const FieldBoundSet &fbs, const BSONObj &order, - const IndexDetails *index = 0, const BSONObj &startKey = BSONObj(), const BSONObj &endKey = BSONObj() ); - QueryPlan( const QueryPlan &other ); + +// QueryPlan( const QueryPlan &other ); /* If true, no other index can do better. */ bool optimal() const { return optimal_; } /* ScanAndOrder processing will be required if true */ diff --git a/dbtests/queryoptimizertests.cpp b/dbtests/queryoptimizertests.cpp index 912550fb996..911682dbbee 100644 --- a/dbtests/queryoptimizertests.cpp +++ b/dbtests/queryoptimizertests.cpp @@ -275,7 +275,7 @@ namespace QueryOptimizerTests { protected: static const char *ns() { return "unittests.QueryPlanTests"; } static NamespaceDetails *nsd() { return nsdetails( ns() ); } - const IndexDetails *index( const BSONObj &key ) { + IndexDetails *index( const BSONObj &key ) { stringstream ss; ss << indexNum_++; string name = ss.str(); @@ -289,6 +289,9 @@ namespace QueryOptimizerTests { assert( false ); return 0; } + int indexno( const BSONObj &key ) { + return nsd()->idxNo( *index(key) ); + } private: dblock lk_; int indexNum_; @@ -297,6 +300,7 @@ namespace QueryOptimizerTests { DBDirectClient Base::client_; // There's a limit of 10 indexes total, make sure not to exceed this in a given test. +#define INDEXNO(x) nsd()->idxNo( *this->index( BSON(x) ) ) #define INDEX(x) this->index( BSON(x) ) auto_ptr< FieldBoundSet > FieldBoundSet_GLOBAL; #define FBS(x) ( FieldBoundSet_GLOBAL.reset( new FieldBoundSet( ns(), x ) ), *FieldBoundSet_GLOBAL ) @@ -304,7 +308,7 @@ namespace QueryOptimizerTests { class NoIndex : public Base { public: void run() { - QueryPlan p( FBS( BSONObj() ), BSONObj(), 0 ); + QueryPlan p( nsd(), -1, FBS( BSONObj() ), BSONObj() ); ASSERT( !p.optimal() ); ASSERT( !p.scanAndOrderRequired() ); ASSERT( !p.exactKeyMatch() ); @@ -321,13 +325,13 @@ namespace QueryOptimizerTests { b2.appendMaxKey( "" ); BSONObj end = b2.obj(); - QueryPlan p( FBS( BSONObj() ), BSON( "a" << 1 ), INDEX( "a" << 1 ) ); + QueryPlan p( nsd(), INDEXNO( "a" << 1 ), FBS( BSONObj() ), BSON( "a" << 1 ) ); ASSERT( !p.scanAndOrderRequired() ); ASSERT( !p.startKey().woCompare( start ) ); ASSERT( !p.endKey().woCompare( end ) ); - QueryPlan p2( FBS( BSONObj() ), BSON( "a" << 1 << "b" << 1 ), INDEX( "a" << 1 << "b" << 1 ) ); + QueryPlan p2( nsd(), INDEXNO( "a" << 1 << "b" << 1 ), FBS( BSONObj() ), BSON( "a" << 1 << "b" << 1 ) ); ASSERT( !p2.scanAndOrderRequired() ); - QueryPlan p3( FBS( BSONObj() ), BSON( "b" << 1 ), INDEX( "a" << 1 ) ); + QueryPlan p3( nsd(), INDEXNO( "a" << 1 ), FBS( BSONObj() ), BSON( "b" << 1 ) ); ASSERT( p3.scanAndOrderRequired() ); ASSERT( !p3.startKey().woCompare( start ) ); ASSERT( !p3.endKey().woCompare( end ) ); @@ -337,7 +341,7 @@ namespace QueryOptimizerTests { class MoreIndexThanNeeded : public Base { public: void run() { - QueryPlan p( FBS( BSONObj() ), BSON( "a" << 1 ), INDEX( "a" << 1 << "b" << 1 ) ); + QueryPlan p( nsd(), INDEXNO( "a" << 1 << "b" << 1 ), FBS( BSONObj() ), BSON( "a" << 1 ) ); ASSERT( !p.scanAndOrderRequired() ); } }; @@ -345,13 +349,13 @@ namespace QueryOptimizerTests { class IndexSigns : public Base { public: void run() { - QueryPlan p( FBS( BSONObj() ), BSON( "a" << 1 << "b" << -1 ), INDEX( "a" << 1 << "b" << -1 ) ); + QueryPlan p( nsd(), INDEXNO( "a" << 1 << "b" << -1 ) , FBS( BSONObj() ), BSON( "a" << 1 << "b" << -1 ) ); ASSERT( !p.scanAndOrderRequired() ); ASSERT_EQUALS( 1, p.direction() ); - QueryPlan p2( FBS( BSONObj() ), BSON( "a" << 1 << "b" << -1 ), INDEX( "a" << 1 << "b" << 1 ) ); + QueryPlan p2( nsd(), INDEXNO( "a" << 1 << "b" << 1 ), FBS( BSONObj() ), BSON( "a" << 1 << "b" << -1 ) ); ASSERT( p2.scanAndOrderRequired() ); ASSERT_EQUALS( 0, p2.direction() ); - QueryPlan p3( FBS( BSONObj() ), BSON( "_id" << 1 ), index( id_obj ) ); + QueryPlan p3( nsd(), indexno( id_obj ), FBS( BSONObj() ), BSON( "_id" << 1 ) ); ASSERT( !p3.scanAndOrderRequired() ); ASSERT_EQUALS( 1, p3.direction() ); } @@ -368,15 +372,15 @@ namespace QueryOptimizerTests { b2.appendMaxKey( "" ); b2.appendMinKey( "" ); BSONObj end = b2.obj(); - QueryPlan p( FBS( BSONObj() ), BSON( "a" << 1 << "b" << -1 ), INDEX( "a" << -1 << "b" << 1 ) ); + QueryPlan p( nsd(), INDEXNO( "a" << -1 << "b" << 1 ),FBS( BSONObj() ), BSON( "a" << 1 << "b" << -1 ) ); ASSERT( !p.scanAndOrderRequired() ); ASSERT_EQUALS( -1, p.direction() ); ASSERT( !p.startKey().woCompare( start ) ); ASSERT( !p.endKey().woCompare( end ) ); - QueryPlan p2( FBS( BSONObj() ), BSON( "a" << -1 << "b" << -1 ), INDEX( "a" << 1 << "b" << 1 ) ); + QueryPlan p2( nsd(), INDEXNO( "a" << 1 << "b" << 1 ), FBS( BSONObj() ), BSON( "a" << -1 << "b" << -1 ) ); ASSERT( !p2.scanAndOrderRequired() ); ASSERT_EQUALS( -1, p2.direction() ); - QueryPlan p3( FBS( BSONObj() ), BSON( "a" << -1 << "b" << -1 ), INDEX( "a" << 1 << "b" << -1 ) ); + QueryPlan p3( nsd(), INDEXNO( "a" << 1 << "b" << -1 ), FBS( BSONObj() ), BSON( "a" << -1 << "b" << -1 ) ); ASSERT( p3.scanAndOrderRequired() ); ASSERT_EQUALS( 0, p3.direction() ); } @@ -393,11 +397,11 @@ namespace QueryOptimizerTests { b2.append( "", 3 ); b2.appendMaxKey( "" ); BSONObj end = b2.obj(); - QueryPlan p( FBS( BSON( "a" << 3 ) ), BSONObj(), INDEX( "a" << -1 << "b" << 1 ) ); + QueryPlan p( nsd(), INDEXNO( "a" << -1 << "b" << 1 ), FBS( BSON( "a" << 3 ) ), BSONObj() ); ASSERT( !p.scanAndOrderRequired() ); ASSERT( !p.startKey().woCompare( start ) ); ASSERT( !p.endKey().woCompare( end ) ); - QueryPlan p2( FBS( BSON( "a" << 3 ) ), BSONObj(), INDEX( "a" << -1 << "b" << 1 ) ); + QueryPlan p2( nsd(), INDEXNO( "a" << -1 << "b" << 1 ), FBS( BSON( "a" << 3 ) ), BSONObj() ); ASSERT( !p2.scanAndOrderRequired() ); ASSERT( !p.startKey().woCompare( start ) ); ASSERT( !p.endKey().woCompare( end ) ); @@ -407,11 +411,11 @@ namespace QueryOptimizerTests { class EqualWithOrder : public Base { public: void run() { - QueryPlan p( FBS( BSON( "a" << 4 ) ), BSON( "b" << 1 ), INDEX( "a" << 1 << "b" << 1 ) ); + QueryPlan p( nsd(), INDEXNO( "a" << 1 << "b" << 1 ), FBS( BSON( "a" << 4 ) ), BSON( "b" << 1 ) ); ASSERT( !p.scanAndOrderRequired() ); - QueryPlan p2( FBS( BSON( "b" << 4 ) ), BSON( "a" << 1 << "c" << 1 ), INDEX( "a" << 1 << "b" << 1 << "c" << 1 ) ); + QueryPlan p2( nsd(), INDEXNO( "a" << 1 << "b" << 1 << "c" << 1 ), FBS( BSON( "b" << 4 ) ), BSON( "a" << 1 << "c" << 1 ) ); ASSERT( !p2.scanAndOrderRequired() ); - QueryPlan p3( FBS( BSON( "b" << 4 ) ), BSON( "a" << 1 << "c" << 1 ), INDEX( "a" << 1 << "b" << 1 ) ); + QueryPlan p3( nsd(), INDEXNO( "a" << 1 << "b" << 1 ), FBS( BSON( "b" << 4 ) ), BSON( "a" << 1 << "c" << 1 ) ); ASSERT( p3.scanAndOrderRequired() ); } }; @@ -419,23 +423,23 @@ namespace QueryOptimizerTests { class Optimal : public Base { public: void run() { - QueryPlan p( FBS( BSONObj() ), BSON( "a" << 1 ), INDEX( "a" << 1 ) ); + QueryPlan p( nsd(), INDEXNO( "a" << 1 ), FBS( BSONObj() ), BSON( "a" << 1 ) ); ASSERT( p.optimal() ); - QueryPlan p2( FBS( BSONObj() ), BSON( "a" << 1 ), INDEX( "a" << 1 << "b" << 1 ) ); + QueryPlan p2( nsd(), INDEXNO( "a" << 1 << "b" << 1 ), FBS( BSONObj() ), BSON( "a" << 1 ) ); ASSERT( p2.optimal() ); - QueryPlan p3( FBS( BSON( "a" << 1 ) ), BSON( "a" << 1 ), INDEX( "a" << 1 << "b" << 1 ) ); + QueryPlan p3( nsd(), INDEXNO( "a" << 1 << "b" << 1 ), FBS( BSON( "a" << 1 ) ), BSON( "a" << 1 ) ); ASSERT( p3.optimal() ); - QueryPlan p4( FBS( BSON( "b" << 1 ) ), BSON( "a" << 1 ), INDEX( "a" << 1 << "b" << 1 ) ); + QueryPlan p4( nsd(), INDEXNO( "a" << 1 << "b" << 1 ), FBS( BSON( "b" << 1 ) ), BSON( "a" << 1 ) ); ASSERT( !p4.optimal() ); - QueryPlan p5( FBS( BSON( "a" << 1 ) ), BSON( "b" << 1 ), INDEX( "a" << 1 << "b" << 1 ) ); + QueryPlan p5( nsd(), INDEXNO( "a" << 1 << "b" << 1 ), FBS( BSON( "a" << 1 ) ), BSON( "b" << 1 ) ); ASSERT( p5.optimal() ); - QueryPlan p6( FBS( BSON( "b" << 1 ) ), BSON( "b" << 1 ), INDEX( "a" << 1 << "b" << 1 ) ); + QueryPlan p6( nsd(), INDEXNO( "a" << 1 << "b" << 1 ), FBS( BSON( "b" << 1 ) ), BSON( "b" << 1 ) ); ASSERT( !p6.optimal() ); - QueryPlan p7( FBS( BSON( "a" << 1 << "b" << 1 ) ), BSON( "a" << 1 ), INDEX( "a" << 1 << "b" << 1 ) ); + QueryPlan p7( nsd(), INDEXNO( "a" << 1 << "b" << 1 ), FBS( BSON( "a" << 1 << "b" << 1 ) ), BSON( "a" << 1 ) ); ASSERT( p7.optimal() ); - QueryPlan p8( FBS( BSON( "a" << 1 << "b" << LT << 1 ) ), BSON( "a" << 1 ), INDEX( "a" << 1 << "b" << 1 ) ); + QueryPlan p8( nsd(), INDEXNO( "a" << 1 << "b" << 1 ), FBS( BSON( "a" << 1 << "b" << LT << 1 ) ), BSON( "a" << 1 ) ); ASSERT( p8.optimal() ); - QueryPlan p9( FBS( BSON( "a" << 1 << "b" << LT << 1 ) ), BSON( "a" << 1 ), INDEX( "a" << 1 << "b" << 1 << "c" << 1 ) ); + QueryPlan p9( nsd(), INDEXNO( "a" << 1 << "b" << 1 << "c" << 1 ), FBS( BSON( "a" << 1 << "b" << LT << 1 ) ), BSON( "a" << 1 ) ); ASSERT( p9.optimal() ); } }; @@ -443,37 +447,37 @@ namespace QueryOptimizerTests { class MoreOptimal : public Base { public: void run() { - QueryPlan p10( FBS( BSON( "a" << 1 ) ), BSONObj(), INDEX( "a" << 1 << "b" << 1 << "c" << 1 ) ); - ASSERT( p10.optimal() ); - QueryPlan p11( FBS( BSON( "a" << 1 << "b" << LT << 1 ) ), BSONObj(), INDEX( "a" << 1 << "b" << 1 << "c" << 1 ) ); - ASSERT( p11.optimal() ); - QueryPlan p12( FBS( BSON( "a" << LT << 1 ) ), BSONObj(), INDEX( "a" << 1 << "b" << 1 << "c" << 1 ) ); - ASSERT( p12.optimal() ); - QueryPlan p13( FBS( BSON( "a" << LT << 1 ) ), BSON( "a" << 1 ), INDEX( "a" << 1 << "b" << 1 << "c" << 1 ) ); - ASSERT( p13.optimal() ); + QueryPlan p10( nsd(), INDEXNO( "a" << 1 << "b" << 1 << "c" << 1 ), FBS( BSON( "a" << 1 ) ), BSONObj() );
+ ASSERT( p10.optimal() );
+ QueryPlan p11( nsd(), INDEXNO( "a" << 1 << "b" << 1 << "c" << 1 ), FBS( BSON( "a" << 1 << "b" << LT << 1 ) ), BSONObj() );
+ ASSERT( p11.optimal() );
+ QueryPlan p12( nsd(), INDEXNO( "a" << 1 << "b" << 1 << "c" << 1 ), FBS( BSON( "a" << LT << 1 ) ), BSONObj() );
+ ASSERT( p12.optimal() );
+ QueryPlan p13( nsd(), INDEXNO( "a" << 1 << "b" << 1 << "c" << 1 ), FBS( BSON( "a" << LT << 1 ) ), BSON( "a" << 1 ) );
+ ASSERT( p13.optimal() ); } }; class KeyMatch : public Base { public: void run() { - QueryPlan p( FBS( BSONObj() ), BSON( "a" << 1 ), INDEX( "a" << 1 ) ); + QueryPlan p( nsd(), INDEXNO( "a" << 1 ), FBS( BSONObj() ), BSON( "a" << 1 ) ); ASSERT( !p.exactKeyMatch() ); - QueryPlan p2( FBS( BSONObj() ), BSON( "a" << 1 ), INDEX( "b" << 1 << "a" << 1 ) ); + QueryPlan p2( nsd(), INDEXNO( "b" << 1 << "a" << 1 ), FBS( BSONObj() ), BSON( "a" << 1 ) ); ASSERT( !p2.exactKeyMatch() ); - QueryPlan p3( FBS( BSON( "b" << "z" ) ), BSON( "a" << 1 ), INDEX( "b" << 1 << "a" << 1 ) ); + QueryPlan p3( nsd(), INDEXNO( "b" << 1 << "a" << 1 ), FBS( BSON( "b" << "z" ) ), BSON( "a" << 1 ) ); ASSERT( !p3.exactKeyMatch() ); - QueryPlan p4( FBS( BSON( "c" << "y" << "b" << "z" ) ), BSON( "a" << 1 ), INDEX( "b" << 1 << "a" << 1 << "c" << 1 ) ); + QueryPlan p4( nsd(), INDEXNO( "b" << 1 << "a" << 1 << "c" << 1 ), FBS( BSON( "c" << "y" << "b" << "z" ) ), BSON( "a" << 1 ) ); ASSERT( !p4.exactKeyMatch() ); - QueryPlan p5( FBS( BSON( "c" << "y" << "b" << "z" ) ), BSONObj(), INDEX( "b" << 1 << "a" << 1 << "c" << 1 ) ); + QueryPlan p5( nsd(), INDEXNO( "b" << 1 << "a" << 1 << "c" << 1 ), FBS( BSON( "c" << "y" << "b" << "z" ) ), BSONObj() ); ASSERT( !p5.exactKeyMatch() ); - QueryPlan p6( FBS( BSON( "c" << LT << "y" << "b" << GT << "z" ) ), BSONObj(), INDEX( "b" << 1 << "a" << 1 << "c" << 1 ) ); + QueryPlan p6( nsd(), INDEXNO( "b" << 1 << "a" << 1 << "c" << 1 ), FBS( BSON( "c" << LT << "y" << "b" << GT << "z" ) ), BSONObj() ); ASSERT( !p6.exactKeyMatch() ); - QueryPlan p7( FBS( BSONObj() ), BSON( "a" << 1 ), INDEX( "b" << 1 ) ); + QueryPlan p7( nsd(), INDEXNO( "b" << 1 ), FBS( BSONObj() ), BSON( "a" << 1 ) ); ASSERT( !p7.exactKeyMatch() ); - QueryPlan p8( FBS( BSON( "b" << "y" << "a" << "z" ) ), BSONObj(), INDEX( "a" << 1 << "b" << 1 ) ); + QueryPlan p8( nsd(), INDEXNO( "a" << 1 << "b" << 1 ), FBS( BSON( "b" << "y" << "a" << "z" ) ), BSONObj() ); ASSERT( p8.exactKeyMatch() ); - QueryPlan p9( FBS( BSON( "a" << "z" ) ), BSON( "a" << 1 ), INDEX( "a" << 1 ) ); + QueryPlan p9( nsd(), INDEXNO( "a" << 1 ), FBS( BSON( "a" << "z" ) ), BSON( "a" << 1 ) ); ASSERT( p9.exactKeyMatch() ); } }; @@ -481,7 +485,7 @@ namespace QueryOptimizerTests { class MoreKeyMatch : public Base { public: void run() { - QueryPlan p( FBS( BSON( "a" << "r" << "b" << NE << "q" ) ), BSON( "a" << 1 ), INDEX( "a" << 1 ) ); + QueryPlan p( nsd(), INDEXNO( "a" << 1 ), FBS( BSON( "a" << "r" << "b" << NE << "q" ) ), BSON( "a" << 1 ) ); ASSERT( !p.exactKeyMatch() ); } }; @@ -489,17 +493,17 @@ namespace QueryOptimizerTests { class ExactKeyQueryTypes : public Base { public: void run() { - QueryPlan p( FBS( BSON( "a" << "b" ) ), BSONObj(), INDEX( "a" << 1 ) ); + QueryPlan p( nsd(), INDEXNO( "a" << 1 ), FBS( BSON( "a" << "b" ) ), BSONObj() ); ASSERT( p.exactKeyMatch() ); - QueryPlan p2( FBS( BSON( "a" << 4 ) ), BSONObj(), INDEX( "a" << 1 ) ); + QueryPlan p2( nsd(), INDEXNO( "a" << 1 ), FBS( BSON( "a" << 4 ) ), BSONObj() ); ASSERT( !p2.exactKeyMatch() ); - QueryPlan p3( FBS( BSON( "a" << BSON( "c" << "d" ) ) ), BSONObj(), INDEX( "a" << 1 ) ); + QueryPlan p3( nsd(), INDEXNO( "a" << 1 ), FBS( BSON( "a" << BSON( "c" << "d" ) ) ), BSONObj() ); ASSERT( !p3.exactKeyMatch() ); BSONObjBuilder b; b.appendRegex( "a", "^ddd" ); - QueryPlan p4( FBS( b.obj() ), BSONObj(), INDEX( "a" << 1 ) ); + QueryPlan p4( nsd(), INDEXNO( "a" << 1 ), FBS( b.obj() ), BSONObj() ); ASSERT( !p4.exactKeyMatch() ); - QueryPlan p5( FBS( BSON( "a" << "z" << "b" << 4 ) ), BSONObj(), INDEX( "a" << 1 << "b" << 1 ) ); + QueryPlan p5( nsd(), INDEXNO( "a" << 1 << "b" << 1 ), FBS( BSON( "a" << "z" << "b" << 4 ) ), BSONObj() ); ASSERT( !p5.exactKeyMatch() ); } }; @@ -507,17 +511,17 @@ namespace QueryOptimizerTests { class Unhelpful : public Base { public: void run() { - QueryPlan p( FBS( BSON( "b" << 1 ) ), BSONObj(), INDEX( "a" << 1 << "b" << 1 ) ); + QueryPlan p( nsd(), INDEXNO( "a" << 1 << "b" << 1 ), FBS( BSON( "b" << 1 ) ), BSONObj() ); ASSERT( !p.bound( "a" ).nontrivial() ); ASSERT( p.unhelpful() ); - QueryPlan p2( FBS( BSON( "b" << 1 << "c" << 1 ) ), BSON( "a" << 1 ), INDEX( "a" << 1 << "b" << 1 ) ); + QueryPlan p2( nsd(), INDEXNO( "a" << 1 << "b" << 1 ), FBS( BSON( "b" << 1 << "c" << 1 ) ), BSON( "a" << 1 ) ); ASSERT( !p2.scanAndOrderRequired() ); ASSERT( !p2.bound( "a" ).nontrivial() ); ASSERT( !p2.unhelpful() ); - QueryPlan p3( FBS( BSON( "b" << 1 << "c" << 1 ) ), BSONObj(), INDEX( "b" << 1 ) ); + QueryPlan p3( nsd(), INDEXNO( "b" << 1 ), FBS( BSON( "b" << 1 << "c" << 1 ) ), BSONObj() ); ASSERT( p3.bound( "b" ).nontrivial() ); ASSERT( !p3.unhelpful() ); - QueryPlan p4( FBS( BSON( "c" << 1 << "d" << 1 ) ), BSONObj(), INDEX( "b" << 1 << "c" << 1 ) ); + QueryPlan p4( nsd(), INDEXNO( "b" << 1 << "c" << 1 ), FBS( BSON( "c" << 1 << "d" << 1 ) ), BSONObj() ); ASSERT( !p4.bound( "b" ).nontrivial() ); ASSERT( p4.unhelpful() ); } |