[SERVER-12848] v2.6.0-rc0 update $addToSet does not add to "a.1" and similar items Created: 23/Feb/14  Updated: 11/Jul/16  Resolved: 03/Mar/14

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

Type: Bug Priority: Major - P3
Reporter: Roman Kuzmin Assignee: Andrew Morrow (Inactive)
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Operating System: ALL
Participants:

 Description   

There is an issue (possibly a bug) and a question (possibly incompatible change).

=======

The issue. Steps to reproduce:

Step 1.
Add an object

{ "_id" : 1, "a" : [ 1, [ ] ] }

to the empty collection test:

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

Step 2.
Let's try to add 1 to the empty array 'a[1]' which is the second item of the array 'a':

> db.test.update({ "_id" : 1 }, { $addToSet : { "a.1" : 1 } })
WriteResult({
        "nMatched" : 0,
        "nUpserted" : 0,
        "nModified" : 0,
        "writeError" : {
                "code" : 57,
                "errmsg" : "a.1 is not valid for storage."
        }
})

The command fails telling "a.1 is not valid for storage.". At the same time a.1 seems to a valid item for $addToSet, i.e. it is an array. This is either a bug or a incompatible change because this used to work fine in v2.4.9.

=======

The question. Steps to reproduce:

Step 1.
Add an object

{ "_id" : 1, "a" : [ 1, 2 ] }

to the empty collection test:

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

Step 2.
Let's try to add 1 to non existent item 'a[3]' of the array 'a':

> db.test.update({ "_id" : 1 }, { $addToSet : { "a.3" : 1 } })
WriteResult({
        "nMatched" : 0,
        "nUpserted" : 0,
        "nModified" : 0,
        "writeError" : {
                "code" : 57,
                "errmsg" : "a.3 is not valid for storage."
        }
})

It fails "a.3 is not valid for storage.". Although it may look reasonable, it used to work fine in v2.4.9. The result was

{ "_id" : 1, "a" : [ 1, 2, null, [1] ] }

, i.e. 'a' was appended with nulls and an array [1] was inserted at the index 3.

The question: is this new behaviour intended?



 Comments   
Comment by Githook User [ 03/Mar/14 ]

Author:

{u'username': u'acmorrow', u'name': u'Andrew Morrow', u'email': u'acm@10gen.com'}

Message: SERVER-12848 Don't validate field names of array children
Branch: master
https://github.com/mongodb/mongo/commit/10e298ddbc22e97a1286c9e7fdcb24366db894b6

Comment by Roman Kuzmin [ 24/Feb/14 ]

Thank you. It's very useful to know.

What about the error on $addToSet with "a.3" (question in the second part)? Is it also a bug or just changed?

Comment by Scott Hernandez (Inactive) [ 24/Feb/14 ]

This should work and the error is a bug.

The $push version works (which is somewhat interesting since the validation is done outside of the modifier):

printjson(db.test.update({_id:1},{$push:{"a.1":1}})); db.test.find({_id:1})

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