summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron <aaron@10gen.com>2011-12-16 15:39:11 -0800
committerAaron <aaron@10gen.com>2011-12-16 15:39:11 -0800
commite82f9ddc53a4fe24a40f190b45dc25b7ed88ed96 (patch)
tree70d618251f82a8a2e6727b0d4ec9ad200865d8df
parent57fa5f296e00af8833bf19c31e3209e8c65bb47b (diff)
downloadmongo-e82f9ddc53a4fe24a40f190b45dc25b7ed88ed96.tar.gz
SERVER-3370 SERVER-3218 backport lexNumCmp fixes to 1.8
-rw-r--r--dbtests/basictests.cpp21
-rw-r--r--jstests/updatea.js6
-rw-r--r--jstests/updateg.js17
-rw-r--r--util/goodies.h29
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 )