-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
Major - P3
-
None
-
Affects Version/s: 8.1.0-rc0, 7.3.4, 8.0.0-rc10, 7.0.13, 6.0.20
-
Component/s: None
-
None
-
Query Execution
-
ALL
-
200
-
None
-
None
-
None
-
None
-
None
-
None
-
None
In the edge case where a $setWindowFields window is empty, a constant output expression can be incorrectly evaluated as if there were a document in the window, when a $sum output is decimal or double. The query below reproduces the problem.
This was found by comparing v5.0.31 (SHA a75f506a) to v6.0.21 (SHA be2ab84d). v5.0's output is correct. v5 and v6 agree on the output before num gets promoted from NumberLong (an int64) to decimal or double, while after that promotion v6 changes its answer to an incorrect one while v5 sticks with its original correct answer.
Passes with $sum(10^16) ----------------------- v5.0.31 a75f506a: { "_id" : 666, "num" : NumberLong("2000000000000000000"), "str" : null } // num: 2x10^18, str: null v6.0.21 be2ab84d: { "_id" : 666, "num" : NumberLong("2000000000000000000"), "str" : null } // num: 2x10^18, str: null Fails with $sum(10^17) - "str" value differs ---------------------- v5.0.31 a75f506a: { "_id" : 666, "num" : 20000000000000000000, "str" : null } // num: 2x10^19, str: null v6.0.21 be2ab84d: { "_id" : 666, "num" : 20000000000000000000, "str" : "foo" } // num: 2x10^19, str: "foo"
These are from running the following minimized query on a collection with 200 arbitrary documents (since nothing in the documents is actually referenced by the query), switching the "output" $sum call between 10^16 and 10^17:
db.test.aggregate([ {"$bucket": { "groupBy": {$sum: [1000, 1000]}, // must appear non-constant to constant folder so multiple groups are kept "boundaries": [111, 222], // MQL requires at least two boundaries "default": 666, // id of missed doc; ALL docs fall into the default bucket // "output": {"num": {"$sum": NumberLong("10000000000000000")}} // 10^16 passes "output": {"num": {"$sum": NumberLong("100000000000000000")}} // 10^17 fails - forces $sum overflow }}, {"$setWindowFields": { "sortBy": {"num": 1}, // needed to produce the failure "output": {"str": {"$last": "foo", "window": {"range": ["unbounded", -10]}}} }} ]);
Explanation: All documents fall into the default bucket (because the query is grouping by constant 2,000, which is larger than the upper bound of the one defined bucket), so only one document is produced by the $bucket stage. This document is
{ "_id" : 666, "num" : 20000000000000000000}
num's value here is 2x^19 as expected. This is a double or decimal, having been promoted from a NumberLong (int64). If it were still an int64 it would be printed as NumberLong("20000000000000000000"), but the max int64 is ~9.2x10^18 so it had to be promoted.
The $setWindowFields stage then adds output field "str" via the expression
{"$last": "foo", "window": {"range": ["unbounded", -10]}}
which says that the value of the "str" field should be the evaluation of subexpression "foo" on the last document in the specified window. The window is from the start of documents to 10 documents prior to the current one, but since there is only one document, not more than 10, the window is empty, so "foo" should not be evaluated on any document. Instead "str" should end up getting set to null by default. (Normally you would expect "foo" to be a reference to a field in the documents, but it's legal for it to be a constant as it is in the repro query.)
- is caused by
-
SERVER-91254 Error when deciding whether documents are inside a window in classic
-
- Closed
-
- related to
-
SERVER-91254 Error when deciding whether documents are inside a window in classic
-
- Closed
-