summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Staple <astaple@cs.stanford.edu>2008-12-04 08:18:07 -0500
committerAaron Staple <astaple@cs.stanford.edu>2008-12-04 08:18:07 -0500
commit0caf3b7529e0b7ee94b805786025060147229b32 (patch)
tree932499308ef92db0e3121f39110c747554ac3a08
parentfa3ec70ca3b8ac0e4b5b2d5a643418ad6a5652f1 (diff)
downloadmongo-0caf3b7529e0b7ee94b805786025060147229b32.tar.gz
Initialize cursor based on query in certain sorting cases where sorting is specified (fix bug 1079).
-rw-r--r--db/query.cpp31
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));
}
}