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

Queries with hash join are always replanned using multi-planner

    • Type: Icon: Bug Bug
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • Query Execution
    • ALL
    • Hide
      db.local.drop();
      db.foreign.drop();
      
      for (let i = 0; i < 10; i++) {
          assert.commandWorked(db.foreign.insertOne({localId: i}));
          for (let j = 0; j < 10; ++j) {
              for (let k = 0; k < 10; ++k) {
                  assert.commandWorked(db.local.insertOne({a: i, b: j, c: i + j, foreignId: k}));
              }
          }
      }
      
      assert.commandWorked(db.local.createIndex({a: 1, c: 1}));
      assert.commandWorked(db.local.createIndex({b: 1, c: 1}));
      assert.commandWorked(db.local.createIndex({a: 1, b: 1}));
      
      const pipeline = [
            {$match: {$or: [
                    {a: {$gte: 9}},
                    {b: {$lte: 2}},
                  ]}},
            {$lookup: {
                    from: "foreign",
                    localField: "foreignId",
                    foreignField: "localId",
                    as: "foreign"
                  }}
      ];
      
      assert.eq(370, db.local.aggregate(pipeline).itcount());
      
      const bigStr = new Array(1024 * 1024).toString();
      for (let i = 10; i < 128; ++i) {
            db.foreign.insertOne({localId: i, data: bigStr});
      }
      
      assert.eq(370, db.local.aggregate(pipeline).itcount()); 
      
      Show
      db.local.drop(); db.foreign.drop(); for (let i = 0; i < 10; i++) { assert .commandWorked(db.foreign.insertOne({localId: i})); for (let j = 0; j < 10; ++j) { for (let k = 0; k < 10; ++k) { assert .commandWorked(db.local.insertOne({a: i, b: j, c: i + j, foreignId: k})); } } } assert .commandWorked(db.local.createIndex({a: 1, c: 1})); assert .commandWorked(db.local.createIndex({b: 1, c: 1})); assert .commandWorked(db.local.createIndex({a: 1, b: 1})); const pipeline = [ {$match: {$or: [ {a: {$gte: 9}}, {b: {$lte: 2}}, ]}}, {$lookup: { from: "foreign" , localField: "foreignId" , foreignField: "localId" , as: "foreign" }} ]; assert .eq(370, db.local.aggregate(pipeline).itcount()); const bigStr = new Array(1024 * 1024).toString(); for (let i = 10; i < 128; ++i) { db.foreign.insertOne({localId: i, data: bigStr}); } assert .eq(370, db.local.aggregate(pipeline).itcount());

      If a query uses sbe plan cache and a hash join, it will be replanned when the foreign collection is no longer eligible for hash join.

      The replanning is always done with a multi-planner that will generate a cache entry that is not pinned.

      However, if the original query was planned using a sub-planner, the plan cache entry is pinned, so when we try to updated it with a non-pinned cache entry, we will get this error:

      Works value is not present in the old cache entry
      

            Assignee:
            Unassigned Unassigned
            Reporter:
            ivan.fefer@mongodb.com Ivan Fefer
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: