From 7bb37b3fd2dfdd3ff3c15634236b4ca487ceda62 Mon Sep 17 00:00:00 2001 From: Eliot Horowitz Date: Mon, 6 Jul 2009 10:42:22 -0400 Subject: [PATCH] fix $(gl)te? scanning for numeric indexes SERVER-99 --- db/queryutil.cpp | 8 ++++++++ dbtests/queryoptimizertests.cpp | 22 ++++++++++++++++++---- jstests/index_check3.js | 6 +++--- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/db/queryutil.cpp b/db/queryutil.cpp index d217d7f5102..33a5604db3d 100644 --- a/db/queryutil.cpp +++ b/db/queryutil.cpp @@ -85,6 +85,14 @@ namespace mongo { default: break; } + + if ( lower_.isNumber() && upper_.type() == MaxKey ){ + upper_ = addObj( BSON( lower_.fieldName() << numeric_limits::max() ) ).firstElement(); + } + else if ( upper_.isNumber() && lower_.type() == MinKey ){ + lower_ = addObj( BSON( upper_.fieldName() << - numeric_limits::max() ) ).firstElement(); + } + } const FieldBound &FieldBound::operator&=( const FieldBound &other ) { diff --git a/dbtests/queryoptimizertests.cpp b/dbtests/queryoptimizertests.cpp index add030c6d4d..912550fb996 100644 --- a/dbtests/queryoptimizertests.cpp +++ b/dbtests/queryoptimizertests.cpp @@ -59,6 +59,19 @@ namespace QueryOptimizerTests { } }; + + class NumericBase : public Base { + public: + NumericBase(){ + o = BSON( "min" << -numeric_limits::max() << "max" << numeric_limits::max() ); + } + + virtual BSONElement lower() { return o["min"]; } + virtual BSONElement upper() { return o["max"]; } + private: + BSONObj o; + }; + class Empty : public Base { virtual BSONObj query() { return BSONObj(); } }; @@ -77,7 +90,7 @@ namespace QueryOptimizerTests { virtual BSONObj query() { return BSON( "a" << 1 << "b" << 2 << "a" << 1 ); } }; - class Lt : public Base { + class Lt : public NumericBase { public: Lt() : o_( BSON( "-" << 1 ) ) {} virtual BSONObj query() { return BSON( "a" << LT << 1 ); } @@ -91,7 +104,7 @@ namespace QueryOptimizerTests { virtual bool upperInclusive() { return true; } }; - class Gt : public Base { + class Gt : public NumericBase { public: Gt() : o_( BSON( "-" << 1 ) ) {} virtual BSONObj query() { return BSON( "a" << GT << 1 ); } @@ -192,10 +205,11 @@ namespace QueryOptimizerTests { void run() { FieldBoundSet fbs( "ns", BSON( "a" << GT << 1 << GT << 5 << LT << 10 << "b" << 4 << "c" << LT << 4 << LT << 6 << "d" << GTE << 0 << GT << 0 << "e" << GTE << 0 << LTE << 10 ) ); BSONObj simple = fbs.simplifiedQuery(); + cout << "simple: " << simple << endl; ASSERT( !simple.getObjectField( "a" ).woCompare( fromjson( "{$gt:5,$lt:10}" ) ) ); ASSERT_EQUALS( 4, simple.getIntField( "b" ) ); - ASSERT( !simple.getObjectField( "c" ).woCompare( fromjson( "{$lt:4}" ) ) ); - ASSERT( !simple.getObjectField( "d" ).woCompare( fromjson( "{$gt:0}" ) ) ); + ASSERT( !simple.getObjectField( "c" ).woCompare( BSON("$gte" << -numeric_limits::max() << "$lt" << 4 ) ) ); + ASSERT( !simple.getObjectField( "d" ).woCompare( BSON("$gt" << 0 << "$lte" << numeric_limits::max() ) ) ); ASSERT( !simple.getObjectField( "e" ).woCompare( fromjson( "{$gte:0,$lte:10}" ) ) ); } }; diff --git a/jstests/index_check3.js b/jstests/index_check3.js index f1615fe0944..62352e5d61c 100644 --- a/jstests/index_check3.js +++ b/jstests/index_check3.js @@ -29,8 +29,8 @@ for ( var i=0; i<100; i++ ){ t.ensureIndex( { foo : 1 } ); -//printjson( t.find( { foo : { $lt : 50 } } ).explain() ); +printjson( t.find( { foo : { $lt : 50 } } ).explain() ); assert.gt( 30 , t.find( { foo : { $lt : 50 } } ).explain().nscanned , "lt" ) -//printjson( t.find( { foo : { $gt : 50 } } ).explain() ); -//assert.gt( 30 , t.find( { foo : { $gt : 50 } } ).explain().nscanned , "gt" ) +printjson( t.find( { foo : { $gt : 50 } } ).explain() ); +assert.gt( 30 , t.find( { foo : { $gt : 50 } } ).explain().nscanned , "gt" )