[SERVER-13317] $unset should get an error on negative array indices, like $pop and $pull do Created: 22/Mar/14  Updated: 22/Mar/14  Resolved: 22/Mar/14

Status: Closed
Project: Core Server
Component/s: Write Ops
Affects Version/s: 2.6.0-rc2
Fix Version/s: None

Type: Improvement Priority: Minor - P4
Reporter: Roman Kuzmin Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to SERVER-13318 Update stats are incorrect after an e... Closed
Participants:

 Description   

$unset should get an error on negative array indices, like $pop and $pull do

Step 1.
Add a document with an array:

> db.test.drop()
> db.test.insert({_id : 1, a : [1, 2]})

Step 2.
Try to $unset at an invalid negative index:

> db.test.update({_id : 1}, {$unset : {"a.-2" : 1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })

Actual result:
The operation is silently ignored.

Expected result:
An error should be returned, like in $pop and $pull cases.

Step 3.
Compare with $pop and $pull invoked with negative indices, they return expected errors:

> db.test.update({_id : 1}, {$pop : {"a.-2" : 1}})
WriteResult({
        "nMatched" : 0,
        "nUpserted" : 0,
        "nModified" : 0,
        "writeError" : {
                "code" : 16837,
                "errmsg" : "cannot use the part (a of a.-2) to traverse the element ({a: [ 1.0, 2.0 ]})"
        }
})
 
> db.test.update({_id : 1}, {$pull : {"a.-2" : 1}})
WriteResult({
        "nMatched" : 0,
        "nUpserted" : 0,
        "nModified" : 0,
        "writeError" : {
                "code" : 16837,
                "errmsg" : "cannot use the part (a of a.-2) to traverse the element ({a: [ 1.0, 2.0 ]})"
        }
})



 Comments   
Comment by Scott Hernandez (Inactive) [ 22/Mar/14 ]

As for the stats, this is byproduct of reporting after an error: SERVER-13318

Comment by Roman Kuzmin [ 22/Mar/14 ]

Yes, this all makes sense, thank you for the detailed answer. Actually, I simply forgot that "a.-1" may be a valid field name for another document.

Comment by Scott Hernandez (Inactive) [ 22/Mar/14 ]

$unset is different than $pop/$pull/$pullAll in a few ways.

  • doesn't target an array
  • doesn't error if the dest (or any part of the path, is missing)
  • the "-1" is ambiguous since it can be a valid field name, just not for an array

These all add up to the system not generating an error in this condition. Doing so now would also be a backwards breaking change with little to no value being added.

If you feel like there is some significant use-case I'm overlooking please provide an example/context to discuss.

Comment by Roman Kuzmin [ 22/Mar/14 ]

Speculation (maybe naive). $pop and $pull both return "nMatched" : 0. Perhaps they do not even try to start an operation, correctly, because the command is invalid in the first place. In contrast, $unset returns "nMatched" : 1, perhaps it does not validate the command before starting the operation though it should, too.

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