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

Write commands using updateOne without shard key path fails spuriously when predicate refers to 'let' parameter

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 7.1.0-rc0
    • Affects Version/s: None
    • Component/s: None
    • Labels:
      None
    • Sharding NYC
    • Fully Compatible
    • ALL
    • Hide

      Repro script:

      (function() {
      "use strict";
      
      const coll = db.test_coll;
      coll.drop();
      
      const testDoc = {
          _id: 4,
          Species: "Song Thrush (Turdus philomelos)",
      };
      assert.commandWorked(coll.insert(testDoc));
      
      assert.commandWorked(db.runCommand({
          delete: coll.getName(),
          let : {target_species: "Song Thrush (Turdus philomelos)"},
          deletes: [{q: {$and: [{_id: 4}, {$expr: {$eq: ["$Species", "$$target_species"]}}]}, limit: 1}]
      }));
      }());
      

      This only repros the problem if run in the sharded collection passthrough with the feature flag enabled. I'm running it with the following resmoke.py invocation:

      python3 buildscripts/resmoke.py run --runAllFeatureFlagTests --suites=sharded_collections_jscore_passthrough repro.js
      
      Show
      Repro script: (function() { "use strict"; const coll = db.test_coll; coll.drop(); const testDoc = { _id: 4, Species: "Song Thrush (Turdus philomelos)", }; assert.commandWorked(coll.insert(testDoc)); assert.commandWorked(db.runCommand({ delete: coll.getName(), let : {target_species: "Song Thrush (Turdus philomelos)"}, deletes: [{q: {$and: [{_id: 4}, {$expr: {$eq: ["$Species", "$$target_species"]}}]}, limit: 1}] })); }()); This only repros the problem if run in the sharded collection passthrough with the feature flag enabled. I'm running it with the following resmoke.py invocation: python3 buildscripts/resmoke.py run --runAllFeatureFlagTests --suites=sharded_collections_jscore_passthrough repro.js
    • Sharding NYC 2023-05-01

      Recently we've seen a few problems where query parsing in sharded contexts can fail because we are failing to plumb through the let parameters and runtimeConstants: see SERVER-75356 and SERVER-71636. This is a similar bug, but it happens for a delete command only when only the following conditions hold:

      • featureFlagUpdateOneWithoutShardKey is enabled
      • The collection is sharded
      • The delete command does not specify the shard key
      • The delete command's predicate refers to a let variable

      In this case, we use a code path which is guarded behind featureFlagUpdateOneWithoutShardKey. We call extractShardKeyFromBasicQuery(), passing through the predicate but not the let parameters or runtime constants. This function then attempts to parse the predicate without providing the let parameters or runtime constants on the ExpressionContext, causing parsing to fail with an error like the following:

      2023-04-12T21:42:50.853Z assert: command failed: {
          "ok" : 0,
          "errmsg" : "Use of undefined variable: target_species",
          "code" : 17276,
          "codeName" : "Location17276",
          "$clusterTime" : {
                  "clusterTime" : Timestamp(1681335770, 82),
                  "signature" : {
                          "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                          "keyId" : NumberLong(0)
                  }
          },
          "operationTime" : Timestamp(1681335770, 82)
      } with original command request: {
          "delete" : "test_coll",
          "let" : {
                  "target_species" : "Song Thrush (Turdus philomelos)"
          },
          "deletes" : [
                  {
                          "q" : {
                                  "$and" : [
                                          {
                                                  "_id" : 4
                                          },
                                          {
                                                  "$expr" : {
                                                          "$eq" : [
                                                                  "$Species",
                                                                  "$$target_species"
                                                          ]
                                                  }
                                          }
                                  ]
                          },
                          "limit" : 1
                  }
          ],
          "lsid" : {
                  "id" : UUID("00eb8ffa-8e7b-45a6-980c-a43e5ec06874")
          },
          "$clusterTime" : {
                  "clusterTime" : Timestamp(1681335770, 82),
                  "signature" : {
                          "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                          "keyId" : NumberLong(0)
                  }
          }
      } on connection: connection to localhost:20003
      

      I've provided complete repro instructions in the "Steps to Reproduce" section. This bug does not exist in the release configuration of the server, so it seems like we should fix it as part of the "updateOne without shard key" project which I believe covers delete as well.

      The solution should be similar to that from SERVER-75356. Namely, we should thread the let parameters and runtime constants through to the ExpressionContext used to parse the query.

            Assignee:
            jason.zhang@mongodb.com Jason Zhang
            Reporter:
            david.storch@mongodb.com David Storch
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: