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

Update with numeric field names inside an array can cause validation to fail

    XMLWordPrintable

Details

    • Bug
    • Status: Closed
    • Critical - P2
    • Resolution: Fixed
    • None
    • 3.4.18, 3.6.9, 4.0.4, 4.1.4
    • Querying
    • None
    • Fully Compatible
    • ALL
    • v4.0, v3.6, v3.4, v3.2
    • Query 2018-10-08
    • 50

    Description

      Full repro:

      (function() {
          const c = db.coll;
          c.drop();
          c.insert({'a': [{}]});
          assert.commandWorked(c.createIndex({'a.0.c': 1}));
          // First 0 is array index.
          // Second 0 is a field name.
          c.update({}, {$set: {'a.0.0.b': 'hi'}});
          const res = assert.commandWorked(c.validate(true));
          assert(res.valid, tojson(res));
      })();
      

      Step 1: Insert a document such as:

      {'a': [{}]}
      

      Step 2: Create an index, such as:

      {'a.0.c': 1}
      

      The key for the document we inserted above is null.

      Now do an update:

      c.update({}, {$set: {'a.0.0.b': 'hi'}});
      

      The update driver determines that this change will not affect any indexes, so the index keys don't get recomputed.

      But when we run validate(), they do get recomputed, and as part of that, validation fails
      because we have a numerical field name in an object nested inside an array:
      https://github.com/mongodb/mongo/blob/a8fe1d82c3c5484c7e8a6402a34bc45ea11d06f1/src/mongo/db/index/btree_key_generator.cpp#L261-L268

      One way to fix this is to just add a special check to the update code.

      Attachments

        Activity

          People

            nicholas.zolnierz@mongodb.com Nicholas Zolnierz
            ian.boros@mongodb.com Ian Boros
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: