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

Date arithmetic allows negative long long results that produce NaN when converted back to Date

    • Type: Icon: Bug Bug
    • Resolution: Unresolved
    • Priority: Icon: Minor - P4 Minor - P4
    • None
    • Affects Version/s: 4.0.28, 6.0.1, 4.4.16, 4.2.22, 5.0.11, 6.1.0-rc1
    • Component/s: None
    • Labels:
      None
    • Query Execution
    • ALL

      Date arithmetic in aggregation pipeline allows negative long long results, but these produce NaN when converted back to Date type.

      SBE has this bug currently. Classic engine is being changed to match SBE via SERVER-68544, so it will have the exact same bug too after that fix. (Before that fix, SBE produces NaN for all under- and overflows, so is even worse.)

      Reproduction in mongo shell:

      1. Create a doc with a date field in it:

      db.a.insert({a: ISODate("2022-01-01")})
      

      2. Add Decimal128(min(long long)) to this date:

      db.a.aggregate([{$project: {addition: {$add: ["$a", NumberDecimal("-9223372036854775808")]}}}])
      

      This will produce an "NaN" result, which is not what we want:

      { "_id" : ObjectId("63110a4b2c0250bba04b450e"), "addition" : ISODate("0NaN-NaN-NaNTNaN:NaN:NaNZ") }
      

      What should happen instead is to receive an error, as is the case with Decimal128(max(long long) - 1) (upper-bound is exclusive, hence the -1 to avoid a different assertion):

      > db.a.aggregate([{$project: {addition: {$add: ["$a", NumberDecimal("9223372036854775806")]}}}])
      uncaught exception: Error: command failed: {
              "ok" : 0,
              "errmsg" : "PlanExecutor error during aggregation :: caused by :: date overflow in $add",
              "code" : 15,
              "codeName" : "Overflow"
      } with original command request: {
              "aggregate" : "a",
              "pipeline" : [
                      {
                              "$project" : {
                                      "addition" : {
                                              "$add" : [
                                                      "$a",
                                                      NumberDecimal("9223372036854775806")
                                              ]
                                      }
                              }
                      }
              ],
              "cursor" : {
      
              },
              "lsid" : {
                      "id" : UUID("dd816a0b-bf37-4460-b199-e7ebb116122b")
              }
      } on connection: connection to 127.0.0.1:27017 : aggregate failed :
      _getErrorWithCode@src/mongo/shell/utils.js:24:13
      doassert@src/mongo/shell/assert.js:18:14
      _assertCommandWorked@src/mongo/shell/assert.js:761:25
      assert.commandWorked@src/mongo/shell/assert.js:853:16
      DB.prototype._runAggregate@src/mongo/shell/db.js:286:12
      DBCollection.prototype.aggregate@src/mongo/shell/collection.js:975:21
      @(shell):1:6
      

      Originally I thought the problem was an undetected underflow, but that was wrong as there is no underflow in this case. The problem is that the long long internal value used to store the date becomes negative, and this produces NaN when converted back to Date. It seems we need to either assert fail when Date arithmetic produces a negative value or support correctly converting negative values to Date values.

            Assignee:
            backlog-query-execution [DO NOT USE] Backlog - Query Execution
            Reporter:
            kevin.cherkauer@mongodb.com Kevin Cherkauer
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: