Object field order is undefined when using $setWindowField

XMLWordPrintableJSON

    • Type: Task
    • Resolution: Fixed
    • Priority: Major - P3
    • 7.2.0-rc0, 7.0.5, 7.1.2, 5.0.27, 6.0.16
    • Affects Version/s: 7.0.0, 7.0.1, 6.3.2
    • Component/s: None
    • None
    • Query Execution
    • Fully Compatible
    • v7.1, v7.0, v6.0, v5.0
    • QE 2023-10-02, QE 2023-10-16
    • 105
    • None
    • 3
    • None
    • None
    • None
    • None
    • None
    • None

      We store $setWindowFields output functions in a StringMap, which has an undefined iteration order. This can cause the field order to vary from one execution to the next. This can lead to surprising results, as illustrated in the following reproduction script:

      foo = db.getSiblingDB("repro");
      foo.bar.drop();
      foo.bar.insert({ "obj" : { "obj" : {  } } });
      foo.bar.insert({});for (let i=0; i<100; i++) {
              res = foo.bar.aggregate([
              {
                "$setWindowFields" : {
                  "output" : {
                    "obj.num" : {
                      "$first" : 1
                    },
                    "obj.obj" : {
                      "$first" : 2
                    }
                  }
                }
              },
              {"$sortByCount" : "$obj" }
              ]);
              printjson(res.toArray());
      }
      

      The output from the above script oscillates between:

      [ { "_id" : { "obj" : 2, "num" : 1 }, "count" : 2 } ] 
      

      and

      [{"_id": {"obj":2,"num":1},"count":1},{"_id":{"num":1,"obj":2},"count":1}]
      

      depending on how the field order comes out.

      Converting the above StringMap to a std::map fixes the oscillation issue, but it's unclear if we should do more to enforce a specific field order.

      This was first spotted by the fuzzer in BF-29818.

            Assignee:
            Rui Liu
            Reporter:
            Colin Stolley
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: