...
The similar $dateFromString expression does not err. The $dateFromParts expression will only err if there is a sort and the year is 0. The documentation says that the value 0 for year is supported. No error results if there are no documents in the database, and the error will occurr no matter what field is sorted on or the direction of the sort. The equivalent find expression will not produce an error.
xgen-internal-githook commented on Fri, 13 Dec 2019 22:19:02 +0000: Author: {'name': 'Justin Seyster', 'email': 'justin.seyster@mongodb.com', 'username': 'jseyster'} Message: SERVER-43360 No year 0 in $dateFromParts expressions Branch: master https://github.com/mongodb/mongo/commit/a599551fa6e997e472187ccc28fe8c6107728092 justin.seyster commented on Fri, 15 Nov 2019 23:43:44 +0000: After talking with asya, we've decided to go with option 1 from my previous post: don't allow the year 0 in $dateFromParts. justin.seyster commented on Fri, 11 Oct 2019 23:24:08 +0000: I have two ways of approaching this that I think make sense. The simplest thing is to change $dateFromParts so that it doesn't allow the year 0 (which is technically 1 BC). We would have to notify downstream-changes, update the docs, and mention the change in our release notes. The code change is trivial, however, and the new semantics make sense. In my testing, all other ways of adding a date to MongoDB consider BC dates to be illegal. Users could still uses a time zone like UTC+03 (as in this example) to create a date that is in the last day of the year 0, but that will not trigger this planning failure (the failing format code will just write out the year as "0000"). If we don't want to do that, the second solution would be what I proposed proposed in Slack, where we update the formatting code to write years before 0 as a negative number. I have a proposal for how to do that (and test it) here: https://mongodbcr.appspot.com/514240046/ I could also extend the proposed change so that $convert from a timestamp to a string still fails when the date is negative, which would allow us to fix this bug while maintaining full compatibility with 4.2 (except for the bug). justin.seyster commented on Fri, 27 Sep 2019 20:25:21 +0000: It turns out the query correctly constructs a Date value from the input $dateFromParts, but goes awry when it tries to convert the Date to a string for the purposes of constructing debug output. The debug string is written with UTC time, which ticks the date back to before the year 0, because Asia/Aden is 3 hours after UTC, and triggers the year range uassert. The debug string gets constructed for this error return, which would normally be recoverable. The failure is because the aggregation planner is trying to construct a query plan that uses an index to satisfy the $sort but is unable to. If the uassert didn't trigger, the planner would make another attempt, this time allowing blocking sorts. Creating the debug string converts the original query into a Value, and the Value string convert calls formatDate, which contains the failing range check. A snafu in creating a debug string (which in this case never gets used, anyway) should definitely not cause a query to fail. I'm not sure yet what the best approach is for fixing this.
Create a new database and populate it with a few files: > db.test.find() { "_id" : ObjectId("5d7fff34f129dbeed236f6f3"), "val" : 1 } { "_id" : ObjectId("5d7fff39f129dbeed236f6f4"), "val" : 2 } { "_id" : ObjectId("5d7fff3df129dbeed236f6f5"), "val" : 3 } Run an aggregation command using `$dateFromParts` with a zero year: > db.runCommand({"aggregate":"test","pipeline":[{"$match":{"$expr":{"$dateFromParts":{"year":0,"minute":14,"millisecond":10,"timezone":"Asia/Aden"}}}},{"$sort":{"val":1}}],"cursor":{}}) { "ok" : 0, "errmsg" : "Could not convert date to string: date component was outside the supported range of 0-9999: -1", "code" : 18537, "codeName" : "Location18537" }