diff options
author | Jason Rassi <rassi@10gen.com> | 2014-08-14 14:25:48 -0400 |
---|---|---|
committer | Jason Rassi <rassi@10gen.com> | 2014-08-15 10:50:15 -0400 |
commit | a1042b421b4a1f046a0228ef316c95f001a4781b (patch) | |
tree | e6e15b0fbb4f021d4060a52c8c1c5faed2da8ad5 | |
parent | be05259d36ec5f44c821c8f2d103a4ee83ebaf53 (diff) | |
download | mongo-a1042b421b4a1f046a0228ef316c95f001a4781b.tar.gz |
SERVER-14128 Disallow requests for non-unique _id indexes
-rw-r--r-- | jstests/core/index_id_unique.js | 25 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_catalog.cpp | 31 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_catalog.h | 4 |
3 files changed, 53 insertions, 7 deletions
diff --git a/jstests/core/index_id_unique.js b/jstests/core/index_id_unique.js new file mode 100644 index 00000000000..ba0a22db47f --- /dev/null +++ b/jstests/core/index_id_unique.js @@ -0,0 +1,25 @@ +// Test creation of the _id index with various values for the "unique" option. + +var coll = db.index_id_unique; + +// Creation of _id index with "non-zero" value for "unique" should succeed. +coll.drop(); +assert.commandWorked(coll.runCommand("create", {autoIndexId: false})); +assert.commandWorked(coll.ensureIndex({_id: 1}, {unique: true})); +coll.drop(); +assert.commandWorked(coll.runCommand("create", {autoIndexId: false})); +assert.commandWorked(coll.ensureIndex({_id: 1}, {unique: 1})); +coll.drop(); +assert.commandWorked(coll.runCommand("create", {autoIndexId: false})); +assert.commandWorked(coll.ensureIndex({_id: 1}, {unique: NumberLong(1)})); + +// Creation of _id index with "zero" value for "unique" should fail. +coll.drop(); +assert.commandWorked(coll.runCommand("create", {autoIndexId: false})); +assert.commandFailed(coll.ensureIndex({_id: 1}, {unique: false})); +coll.drop(); +assert.commandWorked(coll.runCommand("create", {autoIndexId: false})); +assert.commandFailed(coll.ensureIndex({_id: 1}, {unique: 0})); +coll.drop(); +assert.commandWorked(coll.runCommand("create", {autoIndexId: false})); +assert.commandFailed(coll.ensureIndex({_id: 1}, {unique: NumberLong(0)})); diff --git a/src/mongo/db/catalog/index_catalog.cpp b/src/mongo/db/catalog/index_catalog.cpp index b8567599410..77b68682877 100644 --- a/src/mongo/db/catalog/index_catalog.cpp +++ b/src/mongo/db/catalog/index_catalog.cpp @@ -462,6 +462,21 @@ namespace { const NamespaceString& nss = _collection->ns(); + BSONElement vElt = spec["v"]; + if( !vElt.eoo() ) { + if ( !vElt.isNumber() ) { + return Status( ErrorCodes::CannotCreateIndex, + str::stream() << "non-numeric value for \"v\" field:" << vElt ); + } + double v = vElt.Number(); + // note (one day) we may be able to fresh build less versions than we can use + // isASupportedIndexVersionNumber() is what we can use + if ( v != 0 && v != 1 ) { + return Status( ErrorCodes::CannotCreateIndex, + str::stream() << "this version of mongod cannot build new indexes " + << "of version number " << v ); + } + } if ( nss.isSystemDotIndexes() ) return Status( ErrorCodes::CannotCreateIndex, @@ -511,7 +526,13 @@ namespace { << "not allow document removal." ); } - if ( !IndexDescriptor::isIdIndexPattern( key ) ) { + if ( IndexDescriptor::isIdIndexPattern( key ) ) { + BSONElement uniqueElt = spec["unique"]; + if ( !uniqueElt.eoo() && !uniqueElt.trueValue() ) { + return Status( ErrorCodes::CannotCreateIndex, "_id index cannot be non-unique" ); + } + } + else { // for non _id indexes, we check to see if replication has turned off all indexes // we _always_ created _id index repl::ReplicationCoordinator* replCoord = repl::getGlobalReplicationCoordinator(); @@ -1085,13 +1106,9 @@ namespace { int v = DefaultIndexVersionNumber; if( !o["v"].eoo() ) { - double vv = o["v"].Number(); - // note (one day) we may be able to fresh build less versions than we can use - // isASupportedIndexVersionNumber() is what we can use - uassert(14803, str::stream() << "this version of mongod cannot build new indexes of version number " << vv, - vv == 0 || vv == 1); - v = (int) vv; + v = o["v"].numberInt(); } + // idea is to put things we use a lot earlier b.append("v", v); diff --git a/src/mongo/db/catalog/index_catalog.h b/src/mongo/db/catalog/index_catalog.h index a541a8bae0a..2f4ed0b677e 100644 --- a/src/mongo/db/catalog/index_catalog.h +++ b/src/mongo/db/catalog/index_catalog.h @@ -306,6 +306,10 @@ namespace mongo { IndexCatalogEntry* _setupInMemoryStructures(OperationContext* txn, IndexDescriptor* descriptor ); + // Apply a set of transformations to the user-provided index object 'spec' to make it + // conform to the standard for insertion. This function adds the 'v' field if it didn't + // exist, removes the '_id' field if it exists, applies plugin-level transformations if + // appropriate, etc. static BSONObj _fixIndexSpec( const BSONObj& spec ); Status _isSpecOk( const BSONObj& spec ) const; |