Here's a simple repro script, inspired by jstests/core/index_bounds_pipe.js:
(function() { "use strict"; const coll = db.coll; coll.drop(); assert.commandWorked(coll.insert({_id: "a"})); assert.commandWorked(coll.insert({_id: "b"})); assert.commandWorked(coll.insert({_id: "foo"})); // Run a query which results in an auto-parameterized index scan plan being added to the SBE plan // cache. assert.eq(coll.find({_id: /^a/}).itcount(), 1); // This query incorrectly reuses the cached plan, and as a result returns 3 results instead of 2. assert.eq(coll.find({_id: /^a|b/}).itcount(), 2); }());
Note this this only triggers the problem if you also include the changes for SERVER-64315, since this repro depends on the caching of single solution plans.
I believe the problem is similar to SERVER-64776 – namely, the bounds tightness of the regex predicate is not correctly incorporated into the plan cache key. The first regex, /^a/, has exact bounds tightness, and therefore the predicate is "trimmed" and not included as an explicit filter in the execution plan. In contrast, /^a|b/ has inexact bounds and the regex must be reapplied to each index key. However, this query reuses a plan that has no filter stage. Consequently, the predicate does not get reapplied and the query returns extra results.
- is depended on by
-
SERVER-64315 Re-enable caching of single solution plans
- Closed
- is related to
-
SERVER-64776 Modify plan cache key encoding scheme to take into account tightness for $type queries
- Backlog
-
SERVER-33511 Same Query Shape with different regex can give suboptimal index selection
- Closed
-
SERVER-33678 Make regex indexability a factor of query shapes
- Closed