[SERVER-69548] Date arithmetic allows negative long long results that produce NaN when converted back to Date Created: 08/Sep/22  Updated: 05/Dec/22

Status: Backlog
Project: Core Server
Component/s: None
Affects Version/s: 4.0.28, 6.0.1, 4.4.16, 4.2.22, 5.0.11, 6.1.0-rc1
Fix Version/s: None

Type: Bug Priority: Minor - P4
Reporter: Kevin Cherkauer Assignee: Backlog - Query Execution
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Assigned Teams:
Query Execution
Operating System: ALL
Participants:

 Description   

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.


Generated at Thu Feb 08 06:13:45 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.