-
Type: Bug
-
Resolution: Fixed
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: None
-
None
-
Query Optimization
-
Fully Compatible
-
ALL
-
QO 2023-08-07
The fuzzer found this:
> db.c.drop() true > db.c.insert({_id:1, n:NaN}) WriteResult({ "nInserted" : 1 }) > db.c.find({n: {$lt: 0}}) { "_id" : 1, "n" : NaN } > db.c.find({n: {$lt: 0}}) { "_id" : 1, "n" : NaN } > db.c.find({n: {$lte: 0}}) { "_id" : 1, "n" : NaN } > db.c.find({n: {$lt: -Infinity}}) { "_id" : 1, "n" : NaN } > db.c.find({n: {$lte: -Infinity}}) { "_id" : 1, "n" : NaN }
All of these predicates should be false because comparisons with NaN should be false.
I think the simplest place to fix this is in ABT translation. Here's the initial ABT before optimization:
explain : Root [{p0}] Filter [] | EvalFilter [] | | Variable [p0] | PathGet [n] PathTraverse [1] PathComposeM [] | | PathCompare [Gte] Const [nan] | PathCompare [Lt] Const [-inf] Scan [c_d0fd46ae-4b46-4fc0-9552-4201aef6ee7f, {p0}]
When translating MQL to ABT we introduce an explicit lower bound so that the query only matches numbers. That way Lt / Gte can be consistent with intervals / index bounds / a total order. If we made the lower bound `Gt nan` or `Gte -inf` that would fix the bug.
This seems closely related to SERVER-67818 but not exactly the same. It looks like the type-bracketing rules for numbers will have to treat NaN differently than all other numbers.
- related to
-
SERVER-67818 [CQF] NaN $eq NaN should be true
- Closed