Details
-
Bug
-
Resolution: Fixed
-
Major - P3
-
None
-
None
-
None
-
Query Optimization
-
Fully Compatible
-
ALL
-
QO 2023-08-07
Description
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.
Attachments
Issue Links
- related to
-
SERVER-67818 [CQF] NaN $eq NaN should be true
-
- Closed
-