[SERVER-38747] Continually changing behavior of applyOps with an "invalid" update Created: 21/Dec/18  Updated: 06/Dec/22  Resolved: 14/Jan/19

Status: Closed
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Shane Harvey Assignee: Backlog - Replication Team
Resolution: Duplicate Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: File applyOps.js    
Issue Links:
Duplicate
duplicates SERVER-38860 Positional array update behavior of a... Closed
Related
is related to SERVER-38860 Positional array update behavior of a... Closed
Assigned Teams:
Replication
Operating System: ALL
Steps To Reproduce:

// Run applyOps in non-atomic mode.
// For example: applyOps([{op: "i", ns:"test.test", o:{_id:1}}])
function applyOps(ops, extra) {
	// Force non-atomic applyOps mode for this batch
	ops.push({op: "c", ns: "admin.$cmd", o: {applyOps: [{op: "n", ns: "", o: {"msg": "noop"}}]}});
	var command = {
		applyOps: ops,
		writeConcern: {w: "majority"}
	};
	var res = db.adminCommand(command);
	// Avoid noise in output.
	delete res["operationTime"];
	delete res["$clusterTime"];
	return res
}
 
db.test.drop()
db.test.insert({_id:1, a: null});
 
// Test behavior of an invalid update.
print('doc before: ' + tojson(db.test.findOne({_id: 1})));
var res = applyOps([{ns:"test.test", op:"u", o2:{_id:1}, o:{$set:{'a.0':2}}}]);
print('applyOps result: ' + tojson(res))
 
print('doc after : ' + tojson(db.test.findOne({_id: 1})));

Participants:

 Description   

I want to bring to light the continually changing behavior of applyOps with an "invalid" update. This is probably working as designed but I want to confirm that the changes are intentional.

The "invalid" update is attempting to set an array element on a field that is set to null (not an array). See the attached applyOps.js for the repro.

On 3.2 the server reports success and applies the update:

$ mongo applyOps.js
MongoDB shell version v4.0.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.2.18
WARNING: shell and server versions do not match
doc before: { "_id" : 1, "a" : null }
applyOps result: { "applied" : 2, "results" : [ true, true ], "ok" : 1 }
doc after : { "_id" : 1, "a" : { "0" : 2 } }

On 3.4 the server reports an error and does not apply the update:

$ mongo applyOps.js
MongoDB shell version v4.0.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.18
WARNING: shell and server versions do not match
doc before: { "_id" : 1, "a" : null }
applyOps result: {
	"applied" : 1,
	"code" : 16837,
	"codeName" : "Location16837",
	"errmsg" : "cannot use the part (a of a.0) to traverse the element ({a: null})",
	"results" : [
		false
	],
	"ok" : 0
}
doc after : { "_id" : 1, "a" : null }

On 3.6, the server reverts back to the 3.2 behavior, reports success and applies the update:

$ mongo applyOps.js
MongoDB shell version v4.0.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.9
WARNING: shell and server versions do not match
doc before: { "_id" : 1, "a" : null }
applyOps result: { "applied" : 2, "results" : [ true, true ], "ok" : 1 }
doc after : { "_id" : 1, "a" : { "0" : 2 } }

Finally on 4.0, the server reports success and does not apply the update:

$ mongo applyOps.js
MongoDB shell version v4.0.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 4.0.4
doc before: { "_id" : 1, "a" : null }
applyOps result: { "applied" : 2, "results" : [ true, true ], "ok" : 1 }
doc after : { "_id" : 1, "a" : null }


Generated at Thu Feb 08 04:49:53 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.