diff options
author | Aaron Staple <astaple@cs.stanford.edu> | 2008-12-04 08:18:07 -0500 |
---|---|---|
committer | Aaron Staple <astaple@cs.stanford.edu> | 2008-12-04 08:18:07 -0500 |
commit | 0caf3b7529e0b7ee94b805786025060147229b32 (patch) | |
tree | 932499308ef92db0e3121f39110c747554ac3a08 | |
parent | fa3ec70ca3b8ac0e4b5b2d5a643418ad6a5652f1 (diff) | |
download | mongo-0caf3b7529e0b7ee94b805786025060147229b32.tar.gz |
Initialize cursor based on query in certain sorting cases where sorting is specified (fix bug 1079).
-rw-r--r-- | db/query.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/db/query.cpp b/db/query.cpp index f6d1d743180..a51775efbb1 100644 --- a/db/query.cpp +++ b/db/query.cpp @@ -96,6 +96,37 @@ auto_ptr<Cursor> getIndexCursor(const char *ns, BSONObj& query, BSONObj& order, DEV cout << " using index " << d->indexes[i].indexNamespace() << '\n'; if( isSorted ) *isSorted = true; + + // Initialize cursor using query, in the following simple cases. + // (quick fix for bug 1079 ) + if ( orderFields.size() == 1 ) { + string field = *orderFields.begin(); + BSONElement e = query.getField( field.c_str() ); + if ( !e.eoo() && e.type() != RegEx ) { + int op = getGtLtOp( e ); + if ( ( op == JSMatcher::Equality ) || + ( ( op == JSMatcher::LT || op == JSMatcher::LTE ) && reverse ) || + ( ( op == JSMatcher::GT || op == JSMatcher::GTE ) && !reverse ) ) { + BSONObjBuilder b; + if ( op == JSMatcher::Equality ) { + b.append( e ); + } else { + BSONElement ee = e.embeddedObject().firstElement(); + b.appendAs( ee, e.fieldName() ); + } + BSONObj q = b.doneAndDecouple(); + auto_ptr<Cursor> c( new BtreeCursor(d->indexes[i], q, reverse ? -1 : 1, query) ); + if ( op == JSMatcher::GT || op == JSMatcher::LT ) + for( ; c->ok(); c->advance() ) { + BSONElement f = c->current().getField( field.c_str() ); + if ( f.eoo() || !( q.firstElement() == f ) ) + break; + } + return c; + } + } + } + return auto_ptr<Cursor>(new BtreeCursor(d->indexes[i], reverse ? maxKey : emptyObj, reverse ? -1 : 1, query)); } } |