diff options
author | Eliot Horowitz <eliot@10gen.com> | 2013-05-17 09:42:29 -0400 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2013-05-17 12:25:23 -0400 |
commit | 7e516efc7845f62bd89344d7b2daf17632169660 (patch) | |
tree | 810d614b77797729d1cdd55b3c8522c43a12341d | |
parent | 66385352abe589f784b967669d2766929cd1f7fe (diff) | |
download | mongo-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.cpp | 12 | ||||
-rw-r--r-- | src/mongo/db/matcher/expression_leaf.h | 10 | ||||
-rw-r--r-- | src/mongo/db/matcher/expression_leaf_test.cpp | 40 | ||||
-rw-r--r-- | src/mongo/db/matcher/expression_parser.cpp | 10 | ||||
-rw-r--r-- | src/mongo/db/matcher/matcher.cpp | 6 |
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 || |