-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Minor - P4
-
Affects Version/s: None
-
Component/s: Query Execution
-
None
-
Query Execution
-
Fully Compatible
-
ALL
-
None
-
None
-
None
-
None
-
None
-
None
-
None
As part of compiling queries to SBE, the system conducts a type-checking analysis, implemented in mongo::stage_builder::TypeChecker. This analysis tries to identify the set of possible types that could occur at query runtime at each node in an expression tree. This is then used to optimize away unnecessary type checks. Consider the following example:
fillEmpty(subexpr, null)
If the first child expression of the fillEmpty() function returns Nothing, then fillEmpty() returns the value of its second child expression (in this case, null). However, if type analysis concludes that subexpr can never return Nothing, then the fillEmpty() can be optimized away.
The type analysis for the Not node is done incorrectly. The semantics of Not are to return the logical negation when the input is a boolean, and otherwise to return Nothing. A proper implementation of the type analysis should conclude that Not returns a boolean if its input is guaranteed to be a boolean; otherwise Not may return either a boolean or Nothing. What's actually implemented here is a bit different. This code says that Not can return Nothing only if it's child returns Nothing. The bug will cause the fillEmpty() to be erroneously optimized away in this example expression:
fillEmpty(not("foo"), "bar")
This expression should return "bar", but after the incorrect optimization it will return Nothing.
Luckily, this seems to be a latent bug that cannot currently affect real queries. The reason is that when generating ABTs in the stage builders, we always happen to use Not to wrap a boolean expression that can only return boolean or Nothing. In particular, the code generation for the MQL $not expression uses coerceToBool() followed by not().
- related to
-
SERVER-123894 Review TypeChecker::operator() handling of empty TypeSignature
-
- Open
-