Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-17978

Sparse indexes can be assigned to incompatible predicates when query plan is already cached

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 3.1.3
    • Affects Version/s: None
    • Component/s: Querying
    • Fully Compatible
    • ALL
    • Quint Iteration 3.1.2, Quint Iteration 3

      Sparse indexes are considered incompatible with equality predicates that compare to null. This prevents the query {a: null} from selecting a sparse index {a: 1}, as documents that do not contain the field "a" (such as the empty document) would incorrectly be withheld from this query were it to use this index.

      However, this compatibility check is not performed on assignments created from the plan cache. This can lead to missing query results.

      To illustrate, see the following code snippet. The assertion on the last line fails.

      db.foo.drop();
      
      db.foo.insert({});
      db.foo.insert({a: 1, b: 1});
      db.foo.insert({a: 1, b: 2});
      
      db.foo.ensureIndex({a: 1});
      db.foo.ensureIndex({a: 1, b: 1}, {sparse: true});
      
      assert.eq(1, db.foo.find({a: null, b: null}).itcount()); // Picks/caches "a_1" ("a_1_b_1" is incompatible).
      db.foo.getPlanCache().clear();
      assert.eq(1, db.foo.find({a: 1, b: 2}).itcount()); // Picks/caches "a_1_b_1".
      assert.eq(1, db.foo.find({a: null, b: null}).itcount()); // Uses cached plan, assertion fails.
      

            Assignee:
            rassi J Rassi
            Reporter:
            rassi J Rassi
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: