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

tassert tripped when using a cached ixscan plan involving a partialFilterExpression with $or and non-simple collation

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • Query Optimization
    • ALL
    • Hide
      (function() {
      "use strict";
      
      db.test.drop();
      
      const indexList = [
          {
              "obj.array": 1,
          },
          {
              "obj.array": -1,
          },
      ];
      
      const indexOptions = [
          {
              partialFilterExpression: {$or: [{"obj.array": {$exists: true}}, {"obj.array": 5}]},
              collation: {
                  locale: 'ko',
                  strength: 5,
              },
          },
          {},
      ];
      
      const documentList = [
          {
              _id: 1,
              "obj.array": ["some", "string"],
          },
          {
              _id: 2,
              "obj.array": ["some", "other", "string"],
          },
      ];
      
      assert.commandWorked(db.test.insert(documentList));
      
      for (let i = 0; i < indexList.length; i++) {
          db.test.createIndex(indexList[i], indexOptions[i]);
      }
      
      // Run a few aggregations to get a cached entry for {obj.array: {$in: [...]}}
      const aggregationList = [
          {$match: {"obj.array": {$in: [1, 2]}}},
          {$match: {"obj.array": {$in: [1, 2]}}},
          {$match: {"obj.array": {$in: ["Small Analyst", "parsing Zambia Metal"]}}},  // THIS ONE TASSERTS
      ];
      for (let i = 0; i < aggregationList.length; i++) {
          db.test.aggregate(aggregationList[i]).toArray();
      }
      })();
      
      Show
      (function() { "use strict"; db.test.drop(); const indexList = [ { "obj.array": 1, }, { "obj.array": -1, }, ]; const indexOptions = [ { partialFilterExpression: {$or: [{"obj.array": {$exists: true}}, {"obj.array": 5}]}, collation: { locale: 'ko', strength: 5, }, }, {}, ]; const documentList = [ { _id: 1, "obj.array": ["some", "string"], }, { _id: 2, "obj.array": ["some", "other", "string"], }, ]; assert.commandWorked(db.test.insert(documentList)); for (let i = 0; i < indexList.length; i++) { db.test.createIndex(indexList[i], indexOptions[i]); } // Run a few aggregations to get a cached entry for {obj.array: {$in: [...]}} const aggregationList = [ {$match: {"obj.array": {$in: [1, 2]}}}, {$match: {"obj.array": {$in: [1, 2]}}}, {$match: {"obj.array": {$in: ["Small Analyst", "parsing Zambia Metal"]}}}, // THIS ONE TASSERTS ]; for (let i = 0; i < aggregationList.length; i++) { db.test.aggregate(aggregationList[i]).toArray(); } })();
    • 16

      A tassert can be tripped when using a plan cache entry that performs an index scan over a partial index with a filter containing $or and a non-simple collation. The bounds validity check fails when checking whether intervals are ordered correctly.

      Theoretically the query that causes the tassert should not be eligible for the plan cache entry, since it contains a collation-sensitive string value in the predicate.

            Assignee:
            nicholas.zolnierz@mongodb.com Nicholas Zolnierz
            Reporter:
            nicholas.zolnierz@mongodb.com Nicholas Zolnierz
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: