Rooted $or queries (i.e. queries that consist of just an or at the top-level, like {$or: [{...}, {...}, ...]}) and contained $or queries (i.e. queries that have an $or which is AND-related with another predicate or predicates, like {p: 1, $or: [{...}, {...}, ...]}) are planned using the special SubplanStage path.
The SubplanStage reads from and writes to the plan cache on a per-$or clause basis. That is, if you run the query {$or: [{a: 1, b: 1}, {c: 1, d: 1}]} against a server with an empty plan cache, and both clauses are indexed, then the SubplanStage will create two plan cache entries: one for the query {a: 1, b: 1} and another for the query {c: 1, d: 1}. On subsequent executions of the rooted $or query, the plan for each of the two clauses will individually get taken from the plan cache.
When the SubplanStage creates the plan cache entries for each branch, it erroneously associates the entire rooted $or predicate with each plan cache entry. Instead, it should pass the query predicate {a: 1, b: 1} to the plan cache for the first clause of the $or, and should pass {c: 1, d: 1} for the second clause. This is benign in that the bug is only in the plan cache's diagnostics/reporting, however it could be very confusing for users. See "Steps to Reproduce" for details.
The code responsible for this bug is already marked with a TODO:
There is a also descriptive test for this behavior which should be modified alongside the fix:
- depends on
-
SERVER-22833 MatchExpression::toBSON does not necessarily produce a valid query object.
- Closed