[SERVER-4157] findAndModify throws exception when _id is in the update document and "new":true Created: 26/Oct/11  Updated: 07/Mar/14  Resolved: 18/Sep/12

Status: Closed
Project: Core Server
Component/s: Write Ops
Affects Version/s: 1.8.4, 2.0.1
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Barrie Segal Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: findAndModify
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

All


Issue Links:
Duplicate
duplicates SERVER-6913 update allows upsert to "modify" _id Closed
Operating System: ALL
Participants:

 Description   

findAndModify throws exception when _id is in the update document and "new":true

Even though an exception is thrown, the document is still inserted.

This was generated from http://groups.google.com/group/mongodb-user/browse_thread/thread/00623298f8c04836

To Reproduce in 2.0.1: (This is reproducible in 1.8.4 as well, although the outputs are slightly different. )

> db.test.drop()
true
> db.test.save({_id:1, "name" : "Object 1"})
> db.runCommand({findAndModify:"test", "query" :

{ "name" : "asdf" }

, "update" :

{ "_id" : 2, "name" : "Object 2" }

, "upsert" : true } )
{
"lastErrorObject" :

{ "updatedExisting" : false, "n" : 1, "connectionId" : 1, "err" : null, "ok" : 1 }

,
"value" : {

},
"ok" : 1
}
> db.test.find()

{ "_id" : 1, "name" : "Object 1" } { "_id" : 2, "name" : "Object 2" }

> db.runCommand({findAndModify:"test", "query" :

{ "name" : "asdf" }

, "update" :

{ "_id" : 3, "name" : "Object 3" }

, "upsert" : true, "new":true } )
{
"lastErrorObject" :

{ "updatedExisting" : false, "n" : 1, "connectionId" : 1, "err" : null, "ok" : 1 }

,
"errmsg" : "exception: assertion db/ops/../../util/net/../../db/../bson/bsonobjbuilder.h:127",
"code" : 0,
"ok" : 0
}
> db.test.find()

{ "_id" : 1, "name" : "Object 1" } { "_id" : 2, "name" : "Object 2" } { "_id" : 3, "name" : "Object 3" }

Adding a value (any value) to the _id key in the query document prevents an exception from being thrown.
(Example done with 2.0.1)
> db.runCommand({findAndModify:"test", "query" :

{ _id:0, "name" : "asdf" }

, "update" :

{ "_id" : 4, "name" : "Object 4" }

, "upsert" : true, "new":true } )
{
"lastErrorObject" :

{ "updatedExisting" : false, "n" : 1, "connectionId" : 1, "err" : null, "ok" : 1 }

,
"value" : {

},
"ok" : 1
}
> db.runCommand({findAndModify:"test", "query" :

{ _id:5, "name" : "asdf" }

, "update" :

{ "_id" : 5, "name" : "Object 5" }

, "upsert" : true, "new":true } )
{
"lastErrorObject" :

{ "updatedExisting" : false, "n" : 1, "connectionId" : 1, "err" : null, "ok" : 1 }

,
"value" :

{ "_id" : 5, "name" : "Object 5" }

,
"ok" : 1
}
> db.runCommand({findAndModify:"test", "query" :

{ _id:5, "name" : "asdf" }

, "update" :

{ "_id" : 6, "name" : "Object 6" }

, "upsert" : true, "new":true } )
{
"lastErrorObject" :

{ "updatedExisting" : false, "n" : 1, "connectionId" : 1, "err" : null, "ok" : 1 }

,
"value" :

{ "_id" : 5, "name" : "Object 5" }

,
"ok" : 1
}


Generated at Thu Feb 08 03:05:08 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.