summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2013-05-17 09:42:29 -0400
committerEliot Horowitz <eliot@10gen.com>2013-05-17 12:25:23 -0400
commit7e516efc7845f62bd89344d7b2daf17632169660 (patch)
tree810d614b77797729d1cdd55b3c8522c43a12341d
parent66385352abe589f784b967669d2766929cd1f7fe (diff)
downloadmongo-7e516efc7845f62bd89344d7b2daf17632169660.tar.gz
SERVER-6400: ExistsMatchExpression is always looking for a doc, so false is syntactic sugar in parser
-rw-r--r--src/mongo/db/matcher/expression_leaf.cpp12
-rw-r--r--src/mongo/db/matcher/expression_leaf.h10
-rw-r--r--src/mongo/db/matcher/expression_leaf_test.cpp40
-rw-r--r--src/mongo/db/matcher/expression_parser.cpp10
-rw-r--r--src/mongo/db/matcher/matcher.cpp6
5 files changed, 22 insertions, 56 deletions
diff --git a/src/mongo/db/matcher/expression_leaf.cpp b/src/mongo/db/matcher/expression_leaf.cpp
index 938bc2f8b4c..9caf7f50c03 100644
--- a/src/mongo/db/matcher/expression_leaf.cpp
+++ b/src/mongo/db/matcher/expression_leaf.cpp
@@ -310,22 +310,18 @@ namespace mongo {
// ------------------
- Status ExistsMatchExpression::init( const StringData& path, bool exists ) {
+ Status ExistsMatchExpression::init( const StringData& path ) {
initPath( path );
- _exists = exists;
return Status::OK();
}
bool ExistsMatchExpression::matchesSingleElement( const BSONElement& e ) const {
- if ( e.eoo() ) {
- return !_exists;
- }
- return _exists;
+ return !e.eoo();
}
void ExistsMatchExpression::debugString( StringBuilder& debug, int level ) const {
_debugAddSpace( debug, level );
- debug << path() << " exists: " << _exists << "\n";
+ debug << path() << " exists\n";
}
bool ExistsMatchExpression::equivalent( const MatchExpression* other ) const {
@@ -333,7 +329,7 @@ namespace mongo {
return false;
const ExistsMatchExpression* realOther = static_cast<const ExistsMatchExpression*>( other );
- return path() == realOther->path() && _exists == realOther->_exists;
+ return path() == realOther->path();
}
diff --git a/src/mongo/db/matcher/expression_leaf.h b/src/mongo/db/matcher/expression_leaf.h
index 9bf86c73091..3e849392fb9 100644
--- a/src/mongo/db/matcher/expression_leaf.h
+++ b/src/mongo/db/matcher/expression_leaf.h
@@ -206,11 +206,11 @@ namespace mongo {
public:
ExistsMatchExpression() : LeafMatchExpression( EXISTS ){}
- Status init( const StringData& path, bool exists );
+ Status init( const StringData& path );
virtual LeafMatchExpression* shallowClone() const {
ExistsMatchExpression* e = new ExistsMatchExpression();
- e->init( path(), _exists );
+ e->init( path() );
return e;
}
@@ -219,12 +219,6 @@ namespace mongo {
virtual void debugString( StringBuilder& debug, int level ) const;
virtual bool equivalent( const MatchExpression* other ) const;
-
- // this is a terrible name, but trying not to use anythign we may really want
- bool rightSideBool() const { return _exists; }
-
- private:
- bool _exists;
};
class TypeMatchExpression : public MatchExpression {
diff --git a/src/mongo/db/matcher/expression_leaf_test.cpp b/src/mongo/db/matcher/expression_leaf_test.cpp
index 8bd74fc2da7..b27aedd882a 100644
--- a/src/mongo/db/matcher/expression_leaf_test.cpp
+++ b/src/mongo/db/matcher/expression_leaf_test.cpp
@@ -1144,61 +1144,38 @@ namespace mongo {
BSONObj existsNull = BSON( "a" << BSONNULL );
BSONObj doesntExist = BSONObj();
ExistsMatchExpression exists;
- ASSERT( exists.init( "", true ).isOK() );
+ ASSERT( exists.init( "" ).isOK() );
ASSERT( exists.matchesSingleElement( existsInt.firstElement() ) );
ASSERT( exists.matchesSingleElement( existsNull.firstElement() ) );
ASSERT( !exists.matchesSingleElement( doesntExist.firstElement() ) );
}
- TEST( ExistsMatchExpression, MatchesElementExistsFalse ) {
- BSONObj existsInt = BSON( "a" << 5 );
- BSONObj existsNull = BSON( "a" << BSONNULL );
- BSONObj doesntExist = BSONObj();
- ExistsMatchExpression exists;
- ASSERT( exists.init( "", false ).isOK() );
- ASSERT( !exists.matchesSingleElement( existsInt.firstElement() ) );
- ASSERT( !exists.matchesSingleElement( existsNull.firstElement() ) );
- ASSERT( exists.matchesSingleElement( doesntExist.firstElement() ) );
- }
-
TEST( ExistsMatchExpression, MatchesElementExistsTrueValue ) {
BSONObj exists = BSON( "a" << 5 );
BSONObj missing = BSONObj();
ExistsMatchExpression existsTrueValue;
- ExistsMatchExpression existsFalseValue;
- ASSERT( existsTrueValue.init( "", true ).isOK() );
- ASSERT( existsFalseValue.init( "", false ).isOK() );
+ ASSERT( existsTrueValue.init( "" ).isOK() );
ASSERT( existsTrueValue.matchesSingleElement( exists.firstElement() ) );
- ASSERT( !existsFalseValue.matchesSingleElement( exists.firstElement() ) );
ASSERT( !existsTrueValue.matchesSingleElement( missing.firstElement() ) );
- ASSERT( existsFalseValue.matchesSingleElement( missing.firstElement() ) );
}
TEST( ExistsMatchExpression, MatchesScalar ) {
ExistsMatchExpression exists;
- ASSERT( exists.init( "a", true ).isOK() );
+ ASSERT( exists.init( "a" ).isOK() );
ASSERT( exists.matchesBSON( BSON( "a" << 1 ), NULL ) );
ASSERT( exists.matchesBSON( BSON( "a" << BSONNULL ), NULL ) );
ASSERT( !exists.matchesBSON( BSON( "b" << 1 ), NULL ) );
}
- TEST( ExistsMatchExpression, MatchesScalarFalse ) {
- ExistsMatchExpression exists;
- ASSERT( exists.init( "a", false ).isOK() );
- ASSERT( !exists.matchesBSON( BSON( "a" << 1 ), NULL ) );
- ASSERT( !exists.matchesBSON( BSON( "a" << BSONNULL ), NULL ) );
- ASSERT( exists.matchesBSON( BSON( "b" << 1 ), NULL ) );
- }
-
TEST( ExistsMatchExpression, MatchesArray ) {
ExistsMatchExpression exists;
- ASSERT( exists.init( "a", true ).isOK() );
+ ASSERT( exists.init( "a" ).isOK() );
ASSERT( exists.matchesBSON( BSON( "a" << BSON_ARRAY( 4 << 5.5 ) ), NULL ) );
}
TEST( ExistsMatchExpression, ElemMatchKey ) {
ExistsMatchExpression exists;
- ASSERT( exists.init( "a.b", true ).isOK() );
+ ASSERT( exists.init( "a.b" ).isOK() );
MatchDetails details;
details.requestElemMatchKey();
ASSERT( !exists.matchesBSON( BSON( "a" << 1 ), &details ) );
@@ -1213,14 +1190,11 @@ namespace mongo {
TEST( ExistsMatchExpression, Equivalent ) {
ExistsMatchExpression e1;
ExistsMatchExpression e2;
- ExistsMatchExpression e3;
- e1.init( "a" , false );
- e2.init( "a" , true );
- e3.init( "b" , false );
+ e1.init( "a" );
+ e2.init( "b" );
ASSERT( e1.equivalent( &e1 ) );
ASSERT( !e1.equivalent( &e2 ) );
- ASSERT( !e1.equivalent( &e3 ) );
}
/**
diff --git a/src/mongo/db/matcher/expression_parser.cpp b/src/mongo/db/matcher/expression_parser.cpp
index 1b699dc024e..d8531c4675c 100644
--- a/src/mongo/db/matcher/expression_parser.cpp
+++ b/src/mongo/db/matcher/expression_parser.cpp
@@ -142,10 +142,16 @@ namespace mongo {
if ( e.eoo() )
return StatusWithMatchExpression( ErrorCodes::BadValue, "$exists can't be eoo" );
std::auto_ptr<ExistsMatchExpression> temp( new ExistsMatchExpression() );
- Status s = temp->init( name, e.trueValue() );
+ Status s = temp->init( name );
if ( !s.isOK() )
return StatusWithMatchExpression( s );
- return StatusWithMatchExpression( temp.release() );
+ if ( e.trueValue() )
+ return StatusWithMatchExpression( temp.release() );
+ std::auto_ptr<NotMatchExpression> temp2( new NotMatchExpression() );
+ s = temp2->init( temp.release() );
+ if ( !s.isOK() )
+ return StatusWithMatchExpression( s );
+ return StatusWithMatchExpression( temp2.release() );
}
case BSONObj::opTYPE: {
diff --git a/src/mongo/db/matcher/matcher.cpp b/src/mongo/db/matcher/matcher.cpp
index fa7629317f4..94f5ef32df3 100644
--- a/src/mongo/db/matcher/matcher.cpp
+++ b/src/mongo/db/matcher/matcher.cpp
@@ -165,11 +165,7 @@ namespace mongo {
if ( e->matchType() == MatchExpression::EXISTS ){
if ( depth > 0 )
return true;
- const ExistsMatchExpression* exists = static_cast<const ExistsMatchExpression*>(e);
- bool x = !exists->rightSideBool();
- if ( negated )
- x = !x;
- return x;
+ return negated;
}
if ( e->matchType() == MatchExpression::AND ||