Details
Description
Test:
t.save( { a:{ '':1 } } );
|
t.update( {}, { $set:{ 'a.b':2 } } );
|
printjson( db.getLastError() );
|
printjson( t.findOne() );
|
Documents or subdocuments with empty string keys can cause $set updates to that document to fail.
Specifically, $set ing a new field at the same level as an empty-string key, will silently fail. Same for updates to children of siblings to empty-string key ("nephew/niece" fields).
This behaviour sometimes changes depending on the number of updates inside $set.
The test script output should make it clear enough:
-
-
- Single - $set updates *** //php test.php 1 multi_tests
[...]*** TEST 3 ***original: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2}}}update: {"$set":{"tags.m.new":1}}expected: {"_id":"1","tags":{"":{"oops":1},"m":{"new":1,"rock":1},"o":{"funny":2}}}received: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2}}}Test FAILED*** TEST 4 ***original: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2}}}update: {"$set":{"tags.p.p":10}}expected: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2},"p":{"p":10}}}received: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2}}}Test FAILED*** TEST 5 ***original: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2}}}update: {"$set":{"tags.p":1}}expected: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2},"p":1}}received: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2}}}Test FAILED*** Multi - $set updates *** //php test.php 1 multi_tests*** TEST 6 ***original: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2}}}update: {"$set":{"tags.other":10}}expected: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2},"other":10}}received: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2}}}Test FAILED
[...]*** TEST 3 ***original: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2}}}update: {"$set":{"tags.m.new":1,"tags.m.newer":1}}expected: {"_id":"1","tags":{"":{"oops":1},"m":{"new":1,"newer":1,"rock":1},"o":{"funny":2}}}received: {"_id":"1","tags":{"":{"oops":1},"m":{"new":1,"newer":1,"rock":1},"o":{"funny":2}}}Test passed //no problem creating two new tags (one had failed)*** TEST 4 ***original: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2}}}update: {"$set":{"tags.p.p":10,"tags.p.q":11}}expected: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2},"p":{"p":10,"q":11}}}received: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2},"p":{"p":10,"q":11}}}Test passed*** TEST 5 ***original: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2}}}update: {"$set":{"tags.p":1,"tags.q":1}}expected: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2},"p":1,"q":1}}received: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2},"q":1}}Test FAILED //note one update made it through*** TEST 6 ***original: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2}}}update: {"$set":{"tags.other":10,"tags.music":11}}expected: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"music":11,"o":{"funny":2},"other":10}}received: {"_id":"1","tags":{"":{"oops":1},"m":{"rock":1},"o":{"funny":2},"other":10}}Test FAILED //note one update made it through
- Single - $set updates *** //php test.php 1 multi_tests
-
If the empty-string fields are removed from the original object, all tests succeed (run with 0 instead of 1)
Attached tests are PHP (PHPMongo 1.2.9) but behaviour is the same on the shell.
Attachments
Issue Links
- depends on
-
SERVER-6852 Disallow empty path components in documents and queries
-
- Backlog
-
- is duplicated by
-
SERVER-6399 Refactor update() code
-
- Closed
-
- related to
-
SERVER-2051 Disallow empty string keys
-
- Open
-