diff options
author | Aaron <aaron@10gen.com> | 2011-12-16 15:39:11 -0800 |
---|---|---|
committer | Aaron <aaron@10gen.com> | 2011-12-16 15:39:11 -0800 |
commit | e82f9ddc53a4fe24a40f190b45dc25b7ed88ed96 (patch) | |
tree | 70d618251f82a8a2e6727b0d4ec9ad200865d8df | |
parent | 57fa5f296e00af8833bf19c31e3209e8c65bb47b (diff) | |
download | mongo-e82f9ddc53a4fe24a40f190b45dc25b7ed88ed96.tar.gz |
SERVER-3370 SERVER-3218 backport lexNumCmp fixes to 1.8
-rw-r--r-- | dbtests/basictests.cpp | 21 | ||||
-rw-r--r-- | jstests/updatea.js | 6 | ||||
-rw-r--r-- | jstests/updateg.js | 17 | ||||
-rw-r--r-- | util/goodies.h | 29 |
4 files changed, 69 insertions, 4 deletions
diff --git a/dbtests/basictests.cpp b/dbtests/basictests.cpp index 3e0eecd7996..496309c89b1 100644 --- a/dbtests/basictests.cpp +++ b/dbtests/basictests.cpp @@ -399,6 +399,27 @@ namespace BasicTests { ASSERT_EQUALS( -1, lexNumCmp( "a", "0a")); ASSERT_EQUALS( -1, lexNumCmp( "000a", "001a")); ASSERT_EQUALS( 0, lexNumCmp( "010a", "0010a")); + + ASSERT_EQUALS( -1 , lexNumCmp( "a0" , "a00" ) ); + ASSERT_EQUALS( 0 , lexNumCmp( "a.0" , "a.00" ) ); + ASSERT_EQUALS( -1 , lexNumCmp( "a.b.c.d0" , "a.b.c.d00" ) ); + ASSERT_EQUALS( 1 , lexNumCmp( "a.b.c.0.y" , "a.b.c.00.x" ) ); + + ASSERT_EQUALS( -1, lexNumCmp( "a", "a-" ) ); + ASSERT_EQUALS( 1, lexNumCmp( "a-", "a" ) ); + ASSERT_EQUALS( 0, lexNumCmp( "a-", "a-" ) ); + + ASSERT_EQUALS( -1, lexNumCmp( "a", "a-c" ) ); + ASSERT_EQUALS( 1, lexNumCmp( "a-c", "a" ) ); + ASSERT_EQUALS( 0, lexNumCmp( "a-c", "a-c" ) ); + + ASSERT_EQUALS( 1, lexNumCmp( "a-c.t", "a.t" ) ); + ASSERT_EQUALS( -1, lexNumCmp( "a.t", "a-c.t" ) ); + ASSERT_EQUALS( 0, lexNumCmp( "a-c.t", "a-c.t" ) ); + + ASSERT_EQUALS( 1, lexNumCmp( "ac.t", "a.t" ) ); + ASSERT_EQUALS( -1, lexNumCmp( "a.t", "ac.t" ) ); + ASSERT_EQUALS( 0, lexNumCmp( "ac.t", "ac.t" ) ); } }; diff --git a/jstests/updatea.js b/jstests/updatea.js index 9864aa67889..1979201bf58 100644 --- a/jstests/updatea.js +++ b/jstests/updatea.js @@ -46,5 +46,9 @@ assert.eq( orig , t.findOne() , "C2" ); t.update( {} , { $inc: { "a.10" : 1 } } ); orig.a[10]++; +// SERVER-3218 +t.drop() +t.insert({"a":{"c00":1}, 'c':2}) +t.update({"c":2}, {'$inc':{'a.c000':1}}) - +assert.eq( { "c00" : 1 , "c000" : 1 } , t.findOne().a , "D1" ) diff --git a/jstests/updateg.js b/jstests/updateg.js new file mode 100644 index 00000000000..f8d452f71b2 --- /dev/null +++ b/jstests/updateg.js @@ -0,0 +1,17 @@ +// SERVER-3370 check modifiers with field name characters comparing less than '.' character. + +t = db.jstests_updateg; + +t.drop(); +t.update({}, { '$inc' : { 'all.t' : 1, 'all-copy.t' : 1 }}, true); +assert.eq( 1, t.count( {all:{t:1},'all-copy':{t:1}} ) ); + +t.drop(); +t.save({ 'all' : {}, 'all-copy' : {}}); +t.update({}, { '$inc' : { 'all.t' : 1, 'all-copy.t' : 1 }}); +assert.eq( 1, t.count( {all:{t:1},'all-copy':{t:1}} ) ); + +t.drop(); +t.save({ 'all11' : {}, 'all2' : {}}); +t.update({}, { '$inc' : { 'all11.t' : 1, 'all2.t' : 1 }}); +assert.eq( 1, t.count( {all11:{t:1},'all2':{t:1}} ) ); diff --git a/util/goodies.h b/util/goodies.h index 53a74c200bd..3f843b737a3 100644 --- a/util/goodies.h +++ b/util/goodies.h @@ -486,11 +486,30 @@ namespace mongo { return x; } - // for convenience, '{' is greater than anything and stops number parsing + /** + * Non numeric characters are compared lexicographically; numeric substrings + * are compared numerically; dots separate ordered comparable subunits. + * For convenience, character 255 is greater than anything else. + */ inline int lexNumCmp( const char *s1, const char *s2 ) { //cout << "START : " << s1 << "\t" << s2 << endl; + + bool startWord = true; + while( *s1 && *s2 ) { + bool d1 = ( *s1 == '.' ); + bool d2 = ( *s2 == '.' ); + if ( d1 && !d2 ) + return -1; + if ( d2 && !d1 ) + return 1; + if ( d1 && d2 ) { + ++s1; ++s2; + startWord = true; + continue; + } + bool p1 = ( *s1 == (char)255 ); bool p2 = ( *s2 == (char)255 ); //cout << "\t\t " << p1 << "\t" << p2 << endl; @@ -504,8 +523,10 @@ namespace mongo { if ( n1 && n2 ) { // get rid of leading 0s - while ( *s1 == '0' ) s1++; - while ( *s2 == '0' ) s2++; + if ( startWord ) { + while ( *s1 == '0' ) s1++; + while ( *s2 == '0' ) s2++; + } char * e1 = (char*)s1; char * e2 = (char*)s2; @@ -534,6 +555,7 @@ namespace mongo { // otherwise, the numbers are equal s1 = e1; s2 = e2; + startWord = false; continue; } @@ -550,6 +572,7 @@ namespace mongo { return -1; s1++; s2++; + startWord = false; } if ( *s1 ) |