Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-5944

modifier failure with empty string field name and nested fields

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major - P3
    • Resolution: Duplicate
    • Affects Version/s: 2.0.5
    • Fix Version/s: None
    • Component/s: Write Ops
    • Labels:
    • 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).
    • Operating System:
      ALL

      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
            

            	*** 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
            

      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

        1. multi-set.log
          5 kB
        2. single-set.log
          4 kB
        3. test-update-emptystringkey.tgz
          3 kB

          Issue Links

            Activity

              People

              Assignee:
              backlog-server-query Backlog - Query Team
              Reporter:
              yourad_io Tasos Bitsios
              Participants:
              Votes:
              1 Vote for this issue
              Watchers:
              9 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: