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

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Critical - P2 Critical - P2
    • 3.4.18, 3.6.9, 4.0.4, 4.1.4
    • Affects Version/s: None
    • Component/s: Querying
    • Labels:
      None
    • Fully Compatible
    • ALL
    • v4.0, v3.6, v3.4, v3.2
    • Query 2018-10-08
    • 50

      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.

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

              Created:
              Updated:
              Resolved: