0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

FieldBoundSet handles inclusive / exclusive bounds

This commit is contained in:
Aaron 2009-02-27 11:22:12 -05:00
parent 81a684ee5f
commit 4487004dac
3 changed files with 57 additions and 11 deletions

View File

@ -48,7 +48,9 @@ namespace mongo {
FieldBound::FieldBound( const BSONElement &e ) :
lower_( minKey.firstElement() ),
upper_( maxKey.firstElement() ) {
lowerInclusive_( true ),
upper_( maxKey.firstElement() ),
upperInclusive_( true ) {
if ( e.eoo() )
return;
if ( e.type() == RegEx ) {
@ -62,13 +64,15 @@ namespace mongo {
switch( e.getGtLtOp() ) {
case JSMatcher::Equality:
lower_ = e;
upper_ = e;
upper_ = e;
break;
case JSMatcher::LT:
upperInclusive_ = false;
case JSMatcher::LTE:
upper_ = e;
break;
case JSMatcher::GT:
lowerInclusive_ = false;
case JSMatcher::GTE:
lower_ = e;
break;
@ -95,10 +99,23 @@ namespace mongo {
}
const FieldBound &FieldBound::operator&=( const FieldBound &other ) {
if ( other.upper_.woCompare( upper_, false ) < 0 )
int cmp;
cmp = other.upper_.woCompare( upper_, false );
if ( cmp == 0 )
if ( !other.upperInclusive_ )
upperInclusive_ = false;
if ( cmp < 0 ) {
upper_ = other.upper_;
if ( other.lower_.woCompare( lower_, false ) > 0 )
upperInclusive_ = other.upperInclusive_;
}
cmp = other.lower_.woCompare( lower_, false );
if ( cmp == 0 )
if ( !other.lowerInclusive_ )
lowerInclusive_ = false;
if ( cmp > 0 ) {
lower_ = other.lower_;
lowerInclusive_ = other.lowerInclusive_;
}
for( vector< BSONObj >::const_iterator i = other.objData_.begin(); i != other.objData_.end(); ++i )
objData_.push_back( *i );
return *this;
@ -154,9 +171,9 @@ namespace mongo {
else if ( i->second.nontrivial() ) {
BSONObjBuilder c;
if ( i->second.lower().type() != MinKey )
c.appendAs( i->second.lower(), "$gte" );
c.appendAs( i->second.lower(), i->second.lowerInclusive() ? "$gte" : "$gt" );
if ( i->second.upper().type() != MaxKey )
c.appendAs( i->second.upper(), "$lte" );
c.appendAs( i->second.upper(), i->second.upperInclusive() ? "$lte" : "$lt" );
b.append( i->first.c_str(), c.done() );
}
}

View File

@ -35,7 +35,14 @@ namespace mongo {
const FieldBound &operator&=( const FieldBound &other );
BSONElement lower() const { return lower_; }
BSONElement upper() const { return upper_; }
bool equality() const { return lower_.woCompare( upper_, false ) == 0; }
bool lowerInclusive() const { return lowerInclusive_; }
bool upperInclusive() const { return upperInclusive_; }
bool equality() const {
return
lower_.woCompare( upper_, false ) == 0 &&
upperInclusive_ &&
lowerInclusive_;
}
bool nontrivial() const {
return
minKey.firstElement().woCompare( lower_, false ) != 0 ||
@ -45,7 +52,9 @@ namespace mongo {
BSONObj addObj( const BSONObj &o );
string simpleRegexEnd( string regex );
BSONElement lower_;
bool lowerInclusive_;
BSONElement upper_;
bool upperInclusive_;
vector< BSONObj > objData_;
};

View File

@ -156,15 +156,34 @@ namespace QueryOptimizerTests {
BSONObj o1_, o2_;
};
class Equality {
public:
void run() {
FieldBoundSet s( "ns", BSON( "a" << 1 ) );
ASSERT( s.bound( "a" ).equality() );
FieldBoundSet s2( "ns", BSON( "a" << GTE << 1 << LTE << 1 ) );
ASSERT( s2.bound( "a" ).equality() );
FieldBoundSet s3( "ns", BSON( "a" << GT << 1 << LTE << 1 ) );
ASSERT( !s3.bound( "a" ).equality() );
FieldBoundSet s4( "ns", BSON( "a" << GTE << 1 << LT << 1 ) );
ASSERT( !s4.bound( "a" ).equality() );
FieldBoundSet s5( "ns", BSON( "a" << GTE << 1 << LTE << 1 << GT << 1 ) );
ASSERT( !s5.bound( "a" ).equality() );
FieldBoundSet s6( "ns", BSON( "a" << GTE << 1 << LTE << 1 << LT << 1 ) );
ASSERT( !s6.bound( "a" ).equality() );
}
};
class SimplifiedQuery {
public:
void run() {
FieldBoundSet fbs( "ns", BSON( "a" << GT << 1 << GT << 5 << LT << 10 << "b" << 4 << "c" << LT << 4 << LT << 6 << "d" << GTE << 0 ) );
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();
ASSERT( !simple.getObjectField( "a" ).woCompare( fromjson( "{$gte:5,$lte:10}" ) ) );
ASSERT( !simple.getObjectField( "a" ).woCompare( fromjson( "{$gt:5,$lt:10}" ) ) );
ASSERT_EQUALS( 4, simple.getIntField( "b" ) );
ASSERT( !simple.getObjectField( "c" ).woCompare( fromjson( "{$lte:4}" ) ) );
ASSERT( !simple.getObjectField( "d" ).woCompare( fromjson( "{$gte:0}" ) ) );
ASSERT( !simple.getObjectField( "c" ).woCompare( fromjson( "{$lt:4}" ) ) );
ASSERT( !simple.getObjectField( "d" ).woCompare( fromjson( "{$gt:0}" ) ) );
ASSERT( !simple.getObjectField( "e" ).woCompare( fromjson( "{$gte:0,$lte:10}" ) ) );
}
};
@ -933,6 +952,7 @@ namespace QueryOptimizerTests {
add< FieldBoundTests::Regex >();
add< FieldBoundTests::UnhelpfulRegex >();
add< FieldBoundTests::In >();
add< FieldBoundTests::Equality >();
add< FieldBoundTests::SimplifiedQuery >();
add< FieldBoundTests::QueryPatternTest >();
add< FieldBoundTests::NoWhere >();