-
Type: Bug
-
Resolution: Duplicate
-
Priority: Major - P3
-
None
-
Affects Version/s: 2.0.5
-
Component/s: Write Ops
-
Environment:Tests with CLI PHP but confirmed most on shell, too. Two environments checked: Single mongod v2.0.3 on OSX, and v2.0.5 on Linux (EC2 micro instance 2.6.35.14).
-
Query
-
ALL
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
*** 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
*** Multi - $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,"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.
- 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