HashJoin stage followed by a project gives incorrect result with join ordering enabled

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Fixed
    • Priority: Major - P3
    • 8.3.0-rc0
    • Affects Version/s: None
    • Component/s: None
    • Query Execution
    • Fully Compatible
    • ALL
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      This looks like an issue with the stage builder.
      Repro:

      import {assertArrayEq} from "jstests/aggregation/extras/utils.js";
      const conn = MongoRunner.runMongod({setParameter: {allowDiskUseByDefault: true}});
      const db = conn.getDB(jsTestName());
      const coll1 = db[jsTestName() + "_1"];
      const coll2 = db[jsTestName() + "_2"];
      assert.commandWorked(
          coll1.insertMany([
              {
                  "a": null,
                  "b": -1,
              },
              {
                  "a": 1,
                  "b": null,
              },
              {
                  "a": "",
                  "b": null,
              },
              {
                  "a": "str7",
                  "b": 1,
              },
              {
                  "a": null,
                  "b": null,
              },
              {
                  "a": "str6",
                  "b": null,
              },
              {
                  "a": "",
                  "b": -1,
              },
              {
                  "a": null,
                  "b": true,
              },
          ]),
      );
      assert.commandWorked(
          coll2.insertMany([
              {
                  "a": null,
                  "b": 7,
              },
              {
                  "a": "str1",
                  "b": "",
              },
              {
                  "a": "str2",
                  "b": null,
              },
              {
                  "a": false,
                  "b": 10,
              },
              {
                  "a": "str3",
                  "b": "str4",
              },
              {
                  "a": true,
                  "b": "str5",
              },
          ]),
      );
      function testJoinSpilling(coll, lookupPipeline) {
          assert.commandWorked(db.adminCommand({setParameter: 1, internalEnableJoinOptimization: true}));
          const explain = coll.explain("executionStats").aggregate(lookupPipeline);
          print("Explain output: " + tojson(explain));
          const results = coll.aggregate(lookupPipeline).toArray();
          // Disable join optimization and run again to verify the results.
          assert.commandWorked(db.adminCommand({setParameter: 1, internalEnableJoinOptimization: false}));
          const resultsWithoutJoinOptimization = coll.aggregate(lookupPipeline).toArray();
          // Verify results are the same with and without join optimization.
          assertArrayEq({actual: results, expected: resultsWithoutJoinOptimization});
      }
      const lookupPipeline = [
          {
              $lookup: {
                  from: coll2.getName(),
                  localField: "a",
                  foreignField: "b",
                  as: "joined",
              },
          },
          {
              $unwind: "$joined",
          },
          {
              $project: {
                  "_id": 0,
                  "b": 1,
              },
          },
      ];
      testJoinSpilling(coll1, lookupPipeline);
      MongoRunner.stopMongod(conn); 

            Assignee:
            Alberto Massari
            Reporter:
            Projjal Chanda
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: