Skip to content

Commit

Permalink
SERVER-2054 don't uassert due to unique index constraint violation in…
Browse files Browse the repository at this point in the history
… dropdups mode
  • Loading branch information
astaple committed Jul 31, 2011
1 parent a30a6a0 commit 23c7fef
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 6 deletions.
28 changes: 22 additions & 6 deletions db/pdfile.cpp
Expand Up @@ -1193,16 +1193,23 @@ namespace mongo {
BSONObjExternalSorter::Data d = i->next();

try {
btBuilder.addKey(d.first, d.second);
if ( !dupsAllowed && dropDups ) {
LastError::Disabled led( lastError.get() );
btBuilder.addKey(d.first, d.second);
}
else {
btBuilder.addKey(d.first, d.second);
}
}
catch( AssertionException& e ) {
if ( dupsAllowed ) {
// unknow exception??
throw;
}

if( e.interrupted() )
throw;
if( e.interrupted() ) {
killCurrentOp.checkForInterrupt();
}

if ( ! dropDups )
throw;
Expand Down Expand Up @@ -1314,12 +1321,21 @@ namespace mongo {
while ( cc->ok() ) {
BSONObj js = cc->current();
try {
_indexRecord(d, idxNo, js, cc->currLoc(), dupsAllowed);
{
if ( !dupsAllowed && dropDups ) {
LastError::Disabled led( lastError.get() );
_indexRecord(d, idxNo, js, cc->currLoc(), dupsAllowed);
}
else {
_indexRecord(d, idxNo, js, cc->currLoc(), dupsAllowed);
}
}
cc->advance();
}
catch( AssertionException& e ) {
if( e.interrupted() )
throw;
if( e.interrupted() ) {
killCurrentOp.checkForInterrupt();
}

if ( dropDups ) {
DiskLoc toDelete = cc->currLoc();
Expand Down
46 changes: 46 additions & 0 deletions jstests/unique2.js
@@ -1,3 +1,4 @@
// Test unique and dropDups index options.

t = db.jstests_unique2;

Expand All @@ -21,7 +22,9 @@ t.ensureIndex({k:1}, {unique:true});

t.insert({k:3});
t.insert({k:[2,3]});
assert( db.getLastError() );
t.insert({k:[4,3]});
assert( db.getLastError() );

assert( t.count() == 1 ) ;
assert( t.find().sort({k:1}).toArray().length == 1 ) ;
Expand All @@ -33,9 +36,52 @@ t.insert({k:[2,3]});
t.insert({k:[4,3]});
assert( t.count() == 3 ) ;

// Trigger an error, so we can test n of getPrevError() later.
assert.throws( function() { t.find( {$where:'aaa'} ).itcount(); } );
assert( db.getLastError() );
assert.eq( 1, db.getPrevError().nPrev );

t.ensureIndex({k:1}, {unique:true, dropDups:true});
// Check error flag was not set SERVER-2054.
assert( !db.getLastError() );
// Check that offset of pervious error is correct.
assert.eq( 2, db.getPrevError().nPrev );

// Check the dups were dropped.
assert( t.count() == 1 ) ;
assert( t.find().sort({k:1}).toArray().length == 1 ) ;
assert( t.find().sort({k:1}).count() == 1 ) ;

// Check that a new conflicting insert will cause an error.
t.insert({k:[2,3]});
assert( db.getLastError() );

t.drop();

t.insert({k:3});
t.insert({k:[2,3]});
t.insert({k:[4,3]});
assert( t.count() == 3 ) ;


// Now try with a background index op.

// Trigger an error, so we can test n of getPrevError() later.
assert.throws( function() { t.find( {$where:'aaa'} ).itcount(); } );
assert( db.getLastError() );
assert.eq( 1, db.getPrevError().nPrev );

t.ensureIndex({k:1}, {background:true, unique:true, dropDups:true});
// Check error flag was not set SERVER-2054.
assert( !db.getLastError() );
// Check that offset of pervious error is correct.
assert.eq( 2, db.getPrevError().nPrev );

// Check the dups were dropped.
assert( t.count() == 1 ) ;
assert( t.find().sort({k:1}).toArray().length == 1 ) ;
assert( t.find().sort({k:1}).count() == 1 ) ;

// Check that a new conflicting insert will cause an error.
t.insert({k:[2,3]});
assert( db.getLastError() );
13 changes: 13 additions & 0 deletions jstests/uniqueness.js
Expand Up @@ -26,8 +26,21 @@ db.jstests_uniqueness2.drop();
db.jstests_uniqueness2.insert({a:3});
db.jstests_uniqueness2.insert({a:3});
assert( db.jstests_uniqueness2.count() == 2 , 6) ;
db.resetError();
db.jstests_uniqueness2.ensureIndex({a:1}, true);
assert( db.getLastError() , 7);
assert( db.getLastError().match( /E11000/ ) );

// Check for an error message when we index in the background and there are dups
db.jstests_uniqueness2.drop();
db.jstests_uniqueness2.insert({a:3});
db.jstests_uniqueness2.insert({a:3});
assert( db.jstests_uniqueness2.count() == 2 , 6) ;
assert( !db.getLastError() );
db.resetError();
db.jstests_uniqueness2.ensureIndex({a:1}, {unique:true,background:true});
assert( db.getLastError() , 7);
assert( db.getLastError().match( /E11000/ ) );

/* Check that if we update and remove _id, it gets added back by the DB */

Expand Down

0 comments on commit 23c7fef

Please sign in to comment.