Exchange boundaries are not validated, can result in invariant() failure

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Fixed
    • Priority: Critical - P2
    • 4.1.4
    • Affects Version/s: 4.1.2
    • Component/s: Aggregation Framework
    • None
    • Fully Compatible
    • ALL
    • Hide
      (function() {
          "use strict";
      
          db.c.drop();
          assert.commandWorked(db.c.insert({a: 99}));
      
          let result = assert.commandWorked(db.runCommand({
              aggregate: "c",
              pipeline: [],
              exchange: {
                  policy: "range",
                  consumers: NumberInt(2),
                  bufferSize: NumberInt(1024),
                  key: {a: 1},
                  // The last boundary value is not MaxKey, meaning that there could be input
                  // data which we cannot place within a partition.
                  boundaries: [{a: MinKey}, {a: 0}, {a: 50}],
                  consumerids: [NumberInt(0), NumberInt(1)]
              },
              cursor: {batchSize: 0}
          }));
          assert.eq(result.cursors.length, 2);
          assert.eq(result.cursors[0].ok, true);
          assert.eq(result.cursors[1].ok, true);
          let firstCursorId = result.cursors[0].cursor.id;
          let secondCursorId = result.cursors[1].cursor.id;
      
          let firstGetMore =
              assert.commandWorked(db.runCommand({getMore: firstCursorId, collection: "c"}));
          printjson(firstGetMore);
      
          let secondGetMore =
              assert.commandWorked(db.runCommand({getMore: secondCursorId, collection: "c"}));
          printjson(secondGetMore);
      }());
      
      Show
      (function() { "use strict" ; db.c.drop(); assert .commandWorked(db.c.insert({a: 99})); let result = assert .commandWorked(db.runCommand({ aggregate: "c" , pipeline: [], exchange: { policy: "range" , consumers: NumberInt(2), bufferSize: NumberInt(1024), key: {a: 1}, // The last boundary value is not MaxKey, meaning that there could be input // data which we cannot place within a partition. boundaries: [{a: MinKey}, {a: 0}, {a: 50}], consumerids: [NumberInt(0), NumberInt(1)] }, cursor: {batchSize: 0} })); assert .eq(result.cursors.length, 2); assert .eq(result.cursors[0].ok, true ); assert .eq(result.cursors[1].ok, true ); let firstCursorId = result.cursors[0].cursor.id; let secondCursorId = result.cursors[1].cursor.id; let firstGetMore = assert .commandWorked(db.runCommand({getMore: firstCursorId, collection: "c" })); printjson(firstGetMore); let secondGetMore = assert .commandWorked(db.runCommand({getMore: secondCursorId, collection: "c" })); printjson(secondGetMore); }());
    • Query 2018-09-24, Query 2018-10-08
    • None
    • 0
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      The ExchangeSpec accepts an array of boundary values which 1) must be correctly sorted and 2) must begin with MinKey and end with MaxKey. It appears that these constraints are not validated when the exchange option to the aggregate command is parsed. This can result in an invariant() failure downstream (the same invariant failure reported in SERVER-37076). Instead, we should fail the aggregate command with an appropriate user assertion when the exchange boundaries are invalid.

            Assignee:
            Martin Neupauer (Inactive)
            Reporter:
            David Storch
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: