diff --git a/db/pdfile.cpp b/db/pdfile.cpp index e7e10bbf1f1..eab698ecf06 100644 --- a/db/pdfile.cpp +++ b/db/pdfile.cpp @@ -1750,7 +1750,7 @@ namespace mongo { BSONObj io((const char *) obuf); BSONElement idField = io.getField( "_id" ); uassert( 10099 , "_id cannot be an array", idField.type() != Array ); - if( idField.eoo() && !wouldAddIndex && strstr(ns, ".local.") == 0 ) { + if( idField.eoo() && !wouldAddIndex && strstr(ns, ".local.") == 0 && !d->capped) { if( addedID ) *addedID = true; addID = len; diff --git a/db/query.cpp b/db/query.cpp index 0d29ddeb10d..7f1b67887d5 100644 --- a/db/query.cpp +++ b/db/query.cpp @@ -1083,6 +1083,10 @@ namespace mongo { } if ( ! (explain || pq.showDiskLoc()) && isSimpleIdQuery( query ) && !pq.hasOption( QueryOption_CursorTailable ) ) { + + NamespaceDetails* d = nsdetails(ns); + uassert(14815, "capped collections have no _id index by default", !(d && d->capped)); + bool nsFound = false; bool indexFound = false; diff --git a/dbtests/namespacetests.cpp b/dbtests/namespacetests.cpp index 513d90a938f..392917dd6d3 100644 --- a/dbtests/namespacetests.cpp +++ b/dbtests/namespacetests.cpp @@ -625,9 +625,11 @@ namespace NamespaceTests { NamespaceDetails *nsd() const { return nsdetails( ns() )->writingWithExtra(); } - static BSONObj bigObj() { - string as( 187, 'a' ); + static BSONObj bigObj(bool bGenID=false) { BSONObjBuilder b; + if (bGenID) + b.appendOID("_id", 0, true); + string as( 187, 'a' ); b.append( "a", as ); return b.obj(); } @@ -660,12 +662,12 @@ namespace NamespaceTests { public: void run() { create(); - BSONObj b = bigObj(); const int N = 20; const int Q = 16; // these constants depend on the size of the bson object, the extent size allocated by the system too DiskLoc l[ N ]; for ( int i = 0; i < N; ++i ) { + BSONObj b = bigObj(true); l[ i ] = theDataFileMgr.insert( ns(), b.objdata(), b.objsize() ); ASSERT( !l[ i ].isNull() ); ASSERT( nRecords() <= Q ); @@ -717,7 +719,7 @@ namespace NamespaceTests { create(); ASSERT_EQUALS( 2, nExtents() ); - BSONObj b = bigObj(); + BSONObj b = bigObj(true); int N = MinExtentSize / b.objsize() * nExtents() + 5; int T = N - 4; @@ -725,7 +727,8 @@ namespace NamespaceTests { DiskLoc truncAt; //DiskLoc l[ 8 ]; for ( int i = 0; i < N; ++i ) { - DiskLoc a = theDataFileMgr.insert( ns(), b.objdata(), b.objsize() ); + BSONObj bb = bigObj(true); + DiskLoc a = theDataFileMgr.insert( ns(), bb.objdata(), bb.objsize() ); if( T == i ) truncAt = a; ASSERT( !a.isNull() ); @@ -765,6 +768,7 @@ namespace NamespaceTests { // Too big BSONObjBuilder bob; + bob.appendOID("_id", 0, true); bob.append( "a", string( MinExtentSize + 300, 'a' ) ); BSONObj bigger = bob.done(); ASSERT( theDataFileMgr.insert( ns(), bigger.objdata(), bigger.objsize() ).isNull() ); diff --git a/dbtests/querytests.cpp b/dbtests/querytests.cpp index 2fcb2a1deef..e208c995173 100644 --- a/dbtests/querytests.cpp +++ b/dbtests/querytests.cpp @@ -355,12 +355,20 @@ namespace QueryTests { ~TailableQueryOnId() { client().dropCollection( "unittests.querytests.TailableQueryOnId" ); } + + void insertA(const char* ns, int a) { + BSONObjBuilder b; + b.appendOID("_id", 0, true); + b.append("a", a); + insert(ns, b.obj()); + } + void run() { const char *ns = "unittests.querytests.TailableQueryOnId"; BSONObj info; client().runCommand( "unittests", BSON( "create" << "querytests.TailableQueryOnId" << "capped" << true << "autoIndexId" << true ), info ); - insert( ns, BSON( "a" << 0 ) ); - insert( ns, BSON( "a" << 1 ) ); + insertA( ns, 0 ); + insertA( ns, 1 ); auto_ptr< DBClientCursor > c1 = client().query( ns, QUERY( "a" << GT << -1 ), 0, 0, 0, QueryOption_CursorTailable ); OID id; id.init("000000000000000000000000"); @@ -371,7 +379,7 @@ namespace QueryTests { c2->next(); c2->next(); ASSERT( !c2->more() ); - insert( ns, BSON( "a" << 2 ) ); + insertA( ns, 2 ); ASSERT( c1->more() ); ASSERT_EQUALS( 2, c1->next().getIntField( "a" ) ); ASSERT( !c1->more() ); @@ -880,7 +888,10 @@ namespace QueryTests { } void insertNext() { - insert( ns() , BSON( "i" << _n++ ) ); + BSONObjBuilder b; + b.appendOID("_id", 0, true); + b.append("i", _n++); + insert( ns() , b.obj() ); } int _n;