cross-db $lookup tasserts when source DB has a same-named view

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Major - P3
    • None
    • Affects Version/s: 8.0.0, 7.0.31, 8.3.0-rc4
    • Component/s: None
    • None
    • Query Execution
    • ALL
    • Hide

      Minimal jstest (uses MongoRunner; can be dropped under jstests/noPassthrough/):

      const conn = MongoRunner.runMongod({});
      const db = conn.getDB("test");
      
      const testDB = db.getSiblingDB("repro");
      assert.commandWorked(testDB.source.insertOne({x: 1}));
      
      // View in source DB whose coll name matches the cross-DB foreign coll name.
      assert.commandWorked(testDB.createView("collections", "source", []));
      
      // Cross-DB $lookup whose foreign coll name collides with the view above.
      assert.commandWorked(testDB.runCommand({
          aggregate: "source",
          pipeline: [{$lookup: {from: {db: "config", coll: "collections"},
                                localField: "x", foreignField: "_id", as: "out"}}],
          cursor: {}
      }));
      
      MongoRunner.stopMongod(conn);
      

      Expected (master / fixed branches): aggregate succeeds; mongod shuts down with exit code 0.

      Actual (affected branches): aggregate fails with code 9453000, {{errmsg: "No resolved namespace provided for config.collections" }}— the BF-43468 signature.

      Show
      Minimal jstest (uses MongoRunner ; can be dropped under jstests/noPassthrough/ ): const conn = MongoRunner.runMongod({}); const db = conn.getDB( "test" ); const testDB = db.getSiblingDB( "repro" ); assert.commandWorked(testDB.source.insertOne({x: 1})); // View in source DB whose coll name matches the cross-DB foreign coll name. assert.commandWorked(testDB.createView( "collections" , "source" , [])); // Cross-DB $lookup whose foreign coll name collides with the view above. assert.commandWorked(testDB.runCommand({ aggregate: "source" , pipeline: [{$lookup: {from: {db: "config" , coll: "collections" }, localField: "x" , foreignField: "_id" , as: "out" }}], cursor: {} })); MongoRunner.stopMongod(conn); Expected (master / fixed branches): aggregate succeeds; mongod shuts down with exit code 0. Actual (affected branches): aggregate fails with code 9453000 , {{errmsg: "No resolved namespace provided for config.collections" }}— the BF-43468 signature.
    • 200
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      Summary

      An aggregation referencing a cross-database involved namespace (e.g. config.collections via $lookup) tasserts with code 9453000 ("No resolved namespace provided for ...") whenever the source database contains a view whose collection name matches.

      Discovered via jstestfuzz_concurrent (BF-43468).

      Root cause

      resolveInvolvedNamespaces() (in src/mongo/db/commands/query_cmd/aggregation_execution_state.cpp; originally in run_aggregate.cpp) handles cross-db namespaces by checking the source database for a same-named view (SERVER-51886). When one exists, resolveViewDefinition() inserts only the source-db view into the resolved namespace map; the cross-db involvedNs sits in an else branch that never runs. While the map was keyed by collection-name string this was masked by key collisions; SERVER-96197 changed the key to NamespaceString and the missing entry started tripping ExpressionContext::getResolvedNamespace.

      Branch status

      • master: not affected. SERVER-109925 ("Add cross-db $unionWith", Atlas SQL) deleted the cross-DB special-case branch as a side effect.
      • v8.3: affected. SERVER-122573 reverted SERVER-109925 on v8.3, reintroducing the buggy branch.
      • v8.0, v7.0: affected (never had the master cleanup).

      Steps to reproduce: see the dedicated field on this ticket.

            Assignee:
            Rui Liu
            Reporter:
            Chi-I Huang
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: