Skip to content

Commit

Permalink
Merge pull request mongodb#315 from daveh86/SERVER-7017
Browse files Browse the repository at this point in the history
Fix for SERVER-7017
  • Loading branch information
IanWhalen committed Oct 15, 2012
2 parents f81fe24 + 5c18832 commit ce7dcae
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 5 deletions.
25 changes: 25 additions & 0 deletions jstests/rename2.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,28 @@ assert( a.renameCollection( "rename2b" ) , "the command" );

assert.eq( 0 , a.count() , "C" )
assert.eq( 3 , b.count() , "D" )

// Test for SERVER-7017
// We shouldn't rename a collection when one of its indexes will generate a namespace
// that is greater than 120 chars. To do this we create a long index name and try
// and rename the collection to one with a much longer name. We use the test database
// by default and we add this here to ensure we are using it
testDB = db.getSiblingDB("test")
c = "rename2c";
dbc = testDB.getCollection(c);
d = "dest4567890123456789012345678901234567890123456789012345678901234567890"
dbd = testDB.getCollection(d);
dbc.ensureIndex({ "name" : 1,
"date" : 1,
"time" : 1,
"renameCollection" : 1,
"mongodb" : 1,
"testing" : 1,
"data" : 1});
//Checking for the newly created index and the _id index in original collection
assert.eq(2, testDB.system.indexes.find( { "ns" : "test." + c } ).count(), "Long Rename Init");
//Should fail to rename collection as the index namespace is too long
assert.commandFailed( dbc.renameCollection( dbd ) , "Long Rename Exec" );
//Since we failed we should have the 2 indexes unmoved and no indexes under the new collection name
assert.eq(2, testDB.system.indexes.find( { "ns" : "test." + c } ).count(), "Long Rename Result 1");
assert.eq(0, testDB.system.indexes.find( { "ns" : "test." + d } ).count(), "Long Rename Result 2");
31 changes: 26 additions & 5 deletions src/mongo/db/cloner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,9 @@ namespace mongo {

class CmdRenameCollection : public Command {
public:
// Absolute maximum Namespace is 128 incl NUL
// Namespace is 128 minus .$ and $extra so 120 before additions
static const int maxNamespaceLen = 120;
CmdRenameCollection() : Command( "renameCollection" ) {}
virtual bool adminOnly() const {
return true;
Expand All @@ -746,6 +749,28 @@ namespace mongo {
return false;
}

string sourceDB = nsToDatabase(source);
string targetDB = nsToDatabase(target);
string databaseName = sourceDB;
databaseName += ".system.indexes";

int longestIndexNameLength = 0;
vector<BSONObj> oldIndSpec = Helpers::findAll(databaseName, BSON("ns" << source));
for (size_t i = 0; i < oldIndSpec.size(); ++i) {
int thisLength = oldIndSpec[i].getField("name").valuesize();
if (thisLength > longestIndexNameLength) {
longestIndexNameLength = thisLength;
}
}
unsigned int longestAllowed = maxNamespaceLen - longestIndexNameLength - 1;
if (target.size() > longestAllowed) {
StringBuilder sb;
sb << "collection name length of " << target.size()
<< " exceeds maximum length of " << longestAllowed
<< ", allowing for index names";
uasserted(16445, sb.str());
}

bool capped = false;
long long size = 0;
{
Expand Down Expand Up @@ -773,11 +798,7 @@ namespace mongo {
// if we are renaming in the same database, just
// rename the namespace and we're done.
{
char from[256];
nsToDatabase( source.c_str(), from );
char to[256];
nsToDatabase( target.c_str(), to );
if ( strcmp( from, to ) == 0 ) {
if ( sourceDB == targetDB ) {
renameNamespace( source.c_str(), target.c_str(), cmdObj["stayTemp"].trueValue() );
// make sure we drop counters etc
Top::global.collectionDropped( source );
Expand Down

0 comments on commit ce7dcae

Please sign in to comment.