diff --git a/db/btree.h b/db/btree.h index c2652b2614019..e82b38b6ce04f 100644 --- a/db/btree.h +++ b/db/btree.h @@ -200,7 +200,7 @@ namespace mongo { BSONObj endKey; // BSONObj query; // the query we are working on in association with the cursor -- see noMoreMatches() public: - BtreeCursor(IndexDetails&, const BSONObj& startKey, int direction, const BSONObj& query); + BtreeCursor(const IndexDetails&, const BSONObj& startKey, int direction, const BSONObj& query); virtual bool ok() { return !bucket.isNull(); } @@ -283,7 +283,7 @@ namespace mongo { static string simpleRegexEnd( string regex ); - IndexDetails& indexDetails; + const IndexDetails& indexDetails; BSONObj order; DiskLoc bucket; int keyOfs; diff --git a/db/btreecursor.cpp b/db/btreecursor.cpp index 62b73aa30cfa7..4e0c575dcd64e 100644 --- a/db/btreecursor.cpp +++ b/db/btreecursor.cpp @@ -28,7 +28,7 @@ namespace mongo { DiskLoc maxDiskLoc(0x7fffffff, 0x7fffffff); DiskLoc minDiskLoc(0, 1); - BtreeCursor::BtreeCursor(IndexDetails& _id, const BSONObj& k, int _direction, const BSONObj& _query) : + BtreeCursor::BtreeCursor(const IndexDetails& _id, const BSONObj& k, int _direction, const BSONObj& _query) : // query(_query), indexDetails(_id), order(_id.keyPattern()), diff --git a/db/dbcommands.cpp b/db/dbcommands.cpp index ba4437bd75c82..3c937e19ebe0e 100644 --- a/db/dbcommands.cpp +++ b/db/dbcommands.cpp @@ -663,6 +663,9 @@ namespace mongo { virtual bool slaveOk() { return true; } + virtual bool slaveOverrideOk() { + return true; + } virtual bool adminOnly() { return true; } diff --git a/db/namespace.h b/db/namespace.h index 94af22cd94d4f..ea99c21a00caa 100644 --- a/db/namespace.h +++ b/db/namespace.h @@ -142,7 +142,7 @@ namespace mongo { { x : 70, y : 3 } -> { x : 70 } handles our embedded dot notation too. */ - BSONObj getKeyFromQuery(const BSONObj& query) { + BSONObj getKeyFromQuery(const BSONObj& query) const { BSONObj k = keyPattern(); BSONObj res = query.extractFieldsUnDotted(k); assert(res.objsize() != 0); // guard against a seg fault if details is 0 diff --git a/db/query.cpp b/db/query.cpp index b88ae8436925e..33def1372eca1 100644 --- a/db/query.cpp +++ b/db/query.cpp @@ -74,6 +74,19 @@ namespace mongo { } } + auto_ptr< Cursor > getHintCursor( const IndexDetails &ii, BSONObj query, BSONObj order, bool *simpleKeyMatch, bool *isSorted ) { + int direction = matchDirection( ii.keyPattern(), order ); + if ( isSorted ) *isSorted = ( direction != 0 ); + if ( direction == 0 ) + direction = 1; + // NOTE This startKey is incorrect, preserving for the moment so + // we can preserve simpleKeyMatch behavior. + BSONObj startKey = ii.getKeyFromQuery(query); + if ( simpleKeyMatch ) + *simpleKeyMatch = query.nFields() == startKey.nFields(); + return auto_ptr(new BtreeCursor(ii, emptyObj, direction, query)); + } + /* todo: _ use index on partial match with the query parameters @@ -95,17 +108,7 @@ namespace mongo { for (int i = 0; i < d->nIndexes; i++ ) { IndexDetails& ii = d->indexes[i]; if ( ii.indexName() == hintstr ) { - int direction = matchDirection( ii.keyPattern(), order ); - if ( isSorted ) *isSorted = ( direction != 0 ); - if ( direction == 0 ) - direction = 1; - // NOTE This startKey is incorrect, preserving for the moment so - // we can preserve simpleKeyMatch behavior. - BSONObj startKey = ii.getKeyFromQuery(query); - if ( simpleKeyMatch ) - *simpleKeyMatch = query.nFields() == startKey.nFields(); - return auto_ptr( - new BtreeCursor(ii, emptyObj, direction, query)); + return getHintCursor( ii, query, order, simpleKeyMatch, isSorted ); } } } @@ -114,17 +117,7 @@ namespace mongo { for (int i = 0; i < d->nIndexes; i++ ) { IndexDetails& ii = d->indexes[i]; if( ii.keyPattern().woCompare(hintobj) == 0 ) { - int direction = matchDirection( ii.keyPattern(), order ); - if ( isSorted ) *isSorted = ( direction != 0 ); - if ( direction == 0 ) - direction = 1; - // NOTE This startKey is incorrect, preserving for the moment so - // we can preserve simpleKeyMatch behavior. - BSONObj startKey = ii.getKeyFromQuery(query); - if ( simpleKeyMatch ) - *simpleKeyMatch = query.nFields() == startKey.nFields(); - return auto_ptr( - new BtreeCursor(ii, emptyObj, direction, query)); + return getHintCursor( ii, query, order, simpleKeyMatch, isSorted ); } } } diff --git a/jstests/hint1.js b/jstests/hint1.js new file mode 100644 index 0000000000000..19d1dd40cb78f --- /dev/null +++ b/jstests/hint1.js @@ -0,0 +1,8 @@ +p = db.jstests_hint1; + +p.save( { ts: new Date( 1 ), cls: "entry", verticals: "alleyinsider", live: true } ); +p.ensureIndex( { ts: 1 } ); + +e = p.find( { live: true, ts: { $lt: new Date( 1234119308272 ) }, cls: "entry", verticals: " alleyinsider" } ).sort( { ts: -1 } ).hint( { ts: 1 } ).explain(); +assert.eq( e.startKey.ts.getTime(), new Date( 1234119308272 ).getTime() ); +assert.eq( 1, e.endKey.ts.$minElement ); \ No newline at end of file diff --git a/mongo.xcodeproj/project.pbxproj b/mongo.xcodeproj/project.pbxproj index 75bd5c82c2764..a4b610e622c9b 100644 --- a/mongo.xcodeproj/project.pbxproj +++ b/mongo.xcodeproj/project.pbxproj @@ -188,6 +188,7 @@ 93D0C1FB0EF1E267005253B7 /* namespacetests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = namespacetests.cpp; sourceTree = ""; }; 93D6BBF70F265E1100FE5722 /* matchertests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = matchertests.cpp; sourceTree = ""; }; 93D6BC9B0F266FC300FE5722 /* querytests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = querytests.cpp; sourceTree = ""; }; + 93F386400F40E27800967EFA /* hint1.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = hint1.js; sourceTree = ""; }; C6859E8B029090EE04C91782 /* mongo.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = mongo.1; sourceTree = ""; }; /* End PBXFileReference section */ @@ -403,6 +404,7 @@ 93A8D1D10F37544800C92B85 /* jstests */ = { isa = PBXGroup; children = ( + 93F386400F40E27800967EFA /* hint1.js */, 936ABBAA0F3CBE5400D5015F /* recovery */, 936AB9350F3C8AB800D5015F /* _lodeRunner.js */, 936AB4BB0F3A5B0300D5015F /* update3.js */,