diff options
| author | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-14 14:26:38 -0300 |
|---|---|---|
| committer | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-14 14:26:38 -0300 |
| commit | 294bc6ecabf14c09c9bc8644704921dcf97cb44e (patch) | |
| tree | 279b1e0bab53901a1647ac63c1c724f0f789a663 /jstests/core/command_let_variables.js | |
| parent | 70be7c27a251621187a1de533462ae2bb1e3bd39 (diff) | |
| parent | 1e917fd798aa25b7066d4b414b51184f13d5a092 (diff) | |
Update upstream source from tag 'upstream/6.0.10'debian/6.0.10-1
Update to upstream version '6.0.10'
with Debian dir 2d176fa254eee97b139f712fec5709641335a8c3
Diffstat (limited to 'jstests/core/command_let_variables.js')
| -rw-r--r-- | jstests/core/command_let_variables.js | 155 |
1 files changed, 126 insertions, 29 deletions
diff --git a/jstests/core/command_let_variables.js b/jstests/core/command_let_variables.js index 1e4286dbc19..72d6558f6ce 100644 --- a/jstests/core/command_let_variables.js +++ b/jstests/core/command_let_variables.js @@ -6,13 +6,15 @@ (function() { "use strict"; +load("jstests/libs/analyze_plan.js"); load("jstests/libs/fixture_helpers.js"); // For 'isMongos' and 'isSharded'. const testDB = db.getSiblingDB("command_let_variables"); const coll = testDB.command_let_variables; -const targetColl = testDB.command_let_variables_target; +coll.drop(); -assert.commandWorked(testDB.dropDatabase()); +const isMongos = FixtureHelpers.isMongos(testDB); +const isCollSharded = FixtureHelpers.isSharded(coll); const testDocs = [ { @@ -82,7 +84,20 @@ expectedResults = [ assert.eq(coll.aggregate(pipeline, {let : {target_trend: "weak decline"}}).toArray(), expectedResults); -if (!FixtureHelpers.isMongos(testDB)) { +// Test that running explain on the agg command works as expected. +let explain = assert.commandWorked(testDB.runCommand({ + explain: + {aggregate: coll.getName(), pipeline, let : {target_trend: "weak decline"}, cursor: {}}, + verbosity: "executionStats" +})); +if (!isMongos) { + assert(explain.hasOwnProperty("stages"), explain); + assert.neq(explain.stages.length, 0, explain); + let lastStage = explain.stages[explain.stages.length - 1]; + assert.eq(lastStage.nReturned, 2, explain); +} + +if (!isMongos) { // Test that if runtimeConstants and let are both specified, both will coexist. // Runtime constants are not allowed on mongos passthroughs. let constants = { @@ -262,6 +277,20 @@ expectedResults = { assert.eq(result.length, 1); assert.eq(expectedResults, result[0]); +// Test that let parameters work as expected when the find is run as an explain. +explain = assert.commandWorked(testDB.runCommand({ + explain: { + find: coll.getName(), + let : {target_species: "Song Thrush (Turdus philomelos)"}, + filter: {$expr: {$eq: ["$Species", "$$target_species"]}}, + projection: {_id: 0} + }, + verbosity: "executionStats" +})); +if (!isMongos) { + assert.eq(explain.executionStats.nReturned, 1, explain); +} + // Delete tests with let params will delete a record, assert that a point-wise find yields an empty // result, and then restore the collection state for further tests down the line. We can't exercise // a multi-delete here (limit: 0) because of failures in sharded txn passthrough tests. @@ -277,8 +306,24 @@ result = assert .cursor.firstBatch; assert.eq(result.length, 0); -// Test that the .remove() shell helper supports let parameters. assert.commandWorked(coll.insert({_id: 4, Species: "bird_to_remove"})); + +// Test that explain of a delete command works as expected with 'let' parameters. +explain = assert.commandWorked(testDB.runCommand({ + explain: { + delete: coll.getName(), + let : {target_species: "bird_to_remove"}, + deletes: + [{q: {$and: [{_id: 4}, {$expr: {$eq: ["$Species", "$$target_species"]}}]}, limit: 1}] + }, + verbosity: "executionStats" +})); +if (!isMongos) { + let deleteStage = getPlanStage(explain.executionStats.executionStages, "DELETE"); + assert.eq(deleteStage.nWouldDelete, 1, explain); +} + +// Test that the .remove() shell helper supports let parameters. result = assert.commandWorked( coll.remove({$and: [{_id: 4}, {$expr: {$eq: ["$Species", "$$target_species"]}}]}, {justOne: true, let : {target_species: "bird_to_remove"}})); @@ -320,43 +365,67 @@ assert.commandFailedWithCode( {aggregate: coll.getName(), pipeline: [], cursor: {}, let : {REMOVE: "failure"}}), ErrorCodes.FailedToParse); -// Test that let variables can be used within views. -assert.commandWorked(testDB.runCommand({ - create: "core-viewColl", - viewOn: coll.getName(), - pipeline: [{$match: {Species: "Song Thrush (Turdus philomelos)"}}] -})); -assert.commandWorked(testDB.runCommand({ - aggregate: "core-viewColl", - pipeline: [{$addFields: {var : "$$variable"}}], - let : {variable: "Song Thrush"}, - cursor: {} +// Test that let variables can be used within views. Skip in sharded collection passthroughs, since +// dropping the view namespace implicitly recreates the namespace as a sharded collection. +if (!isCollSharded) { + const viewName = "core-viewColl"; + testDB[viewName].drop(); + assert.commandWorked(testDB.runCommand({ + create: viewName, + viewOn: coll.getName(), + pipeline: [{$match: {Species: "Song Thrush (Turdus philomelos)"}}] + })); + assert.commandWorked(testDB.runCommand({ + aggregate: viewName, + pipeline: [{$addFields: {var : "$$variable"}}], + let : {variable: "Song Thrush"}, + cursor: {} + })); +} + +assert.commandWorked(coll.insert({_id: 5, Species: "spy_bird"})); + +// Test that explain of findAndModify works correctly with let parameters. +explain = assert.commandWorked(testDB.runCommand({ + explain: { + findAndModify: coll.getName(), + let : {target_species: "spy_bird"}, + // Querying on _id field for sharded collection passthroughs. + query: {$and: [{_id: 5}, {$expr: {$eq: ["$Species", "$$target_species"]}}]}, + update: {Species: "questionable_bird"}, + new: true + }, + verbosity: "executionStats" })); +if (!isMongos) { + let updateStage = getPlanStage(explain.executionStats.executionStages, "UPDATE"); + assert.eq(updateStage.nMatched, 1, explain); + assert.eq(updateStage.nWouldModify, 1, explain); +} // Test that findAndModify works correctly with let parameter arguments. -assert.commandWorked(coll.insert({_id: 5, Species: "spy_bird"})); -result = testDB.runCommand({ +result = assert.commandWorked(testDB.runCommand({ findAndModify: coll.getName(), let : {target_species: "spy_bird"}, // Querying on _id field for sharded collection passthroughs. query: {$and: [{_id: 5}, {$expr: {$eq: ["$Species", "$$target_species"]}}]}, update: {Species: "questionable_bird"}, new: true -}); +})); expectedResults = { _id: 5, Species: "questionable_bird" }; assert.eq(expectedResults, result.value, result); -result = testDB.runCommand({ +result = assert.commandWorked(testDB.runCommand({ findAndModify: coll.getName(), let : {species_name: "not_a_bird", realSpecies: "dino"}, // Querying on _id field for sharded collection passthroughs. query: {$and: [{_id: 5}, {$expr: {$eq: ["$Species", "questionable_bird"]}}]}, update: [{$project: {Species: "$$species_name"}}, {$addFields: {suspect: "$$realSpecies"}}], new: true -}); +})); expectedResults = { _id: 5, Species: "not_a_bird", @@ -364,12 +433,31 @@ expectedResults = { }; assert.eq(expectedResults, result.value, result); +// Test that explain of update works correctly with let parameters. +explain = assert.commandWorked(testDB.runCommand({ + explain: { + update: coll.getName(), + updates: [{ + q: {_id: 3, $expr: {$eq: ["$Species", "$$target_species"]}}, + u: [{$set: {Species: "$$new_name"}}], + }], + let : {target_species: "Chaffinch (Fringilla coelebs)", new_name: "Chaffinch"} + }, + verbosity: "executionStats" +})); +if (!isMongos) { + let updateStage = getPlanStage(explain.executionStats.executionStages, "UPDATE"); + assert.eq(updateStage.nMatched, 1, explain); + assert.eq(updateStage.nWouldModify, 1, explain); +} + // Test that update respects different parameters in both the query and update part. result = assert.commandWorked(testDB.runCommand({ update: coll.getName(), - updates: [ - {q: {$expr: {$eq: ["$Species", "$$target_species"]}}, u: [{$set: {Species: "$$new_name"}}]} - ], + updates: [{ + q: {_id: 3, $expr: {$eq: ["$Species", "$$target_species"]}}, + u: [{$set: {Species: "$$new_name"}}], + }], let : {target_species: "Chaffinch (Fringilla coelebs)", new_name: "Chaffinch"} })); assert.eq(result.n, 1); @@ -387,8 +475,8 @@ assert.eq(result.cursor.firstBatch.length, 1); result = assert.commandWorked(testDB.runCommand({ update: coll.getName(), updates: [{ - q: {$expr: {$eq: ["$Species", "$$target_species"]}}, - u: [{$set: {Timestamp: "$$NOW"}}, {$set: {Species: "$$new_name"}}] + q: {_id: 3, $expr: {$eq: ["$Species", "$$target_species"]}}, + u: [{$set: {Timestamp: "$$NOW"}}, {$set: {Species: "$$new_name"}}], }], let : {target_species: "Chaffinch", new_name: "Pied Piper"} })); @@ -403,6 +491,12 @@ result = assert.commandWorked( testDB.runCommand({find: coll.getName(), filter: {$expr: {$eq: ["$Species", "Pied Piper"]}}})); assert.eq(result.cursor.firstBatch.length, 1, result); +// This forces a multi-statement transaction to commit if this test is running in one of the +// multi-statement transaction passthrough suites. We need to do this to ensure the updates above +// commit before running an update that will fail, as the failed update aborts the entire +// transaction and rolls back the updates above. +assert.commandWorked(testDB.runCommand({ping: 1})); + // Test that undefined let params in the update's query part fail gracefully. assert.commandFailedWithCode(testDB.runCommand({ update: coll.getName(), @@ -418,8 +512,8 @@ assert.commandFailedWithCode(testDB.runCommand({ assert.commandFailedWithCode(testDB.runCommand({ update: coll.getName(), updates: [{ - q: {$expr: {$eq: ["$Species", "Chaffinch (Fringilla coelebs)"]}}, - u: [{$set: {Species: "$$new_name"}}] + q: {_id: 3, $expr: {$eq: ["$Species", "Chaffinch (Fringilla coelebs)"]}}, + u: [{$set: {Species: "$$new_name"}}], }], let : {cat: "not_a_bird"} }), @@ -427,7 +521,7 @@ assert.commandFailedWithCode(testDB.runCommand({ // Test that the .update() shell helper supports let parameters. result = assert.commandWorked( - coll.update({$expr: {$eq: ["$Species", "$$target_species"]}}, + coll.update({_id: 3, $expr: {$eq: ["$Species", "$$target_species"]}}, [{$set: {Species: "$$new_name"}}], {let : {target_species: "Pied Piper", new_name: "Chaffinch"}})); assert.eq(result.nMatched, 1); @@ -519,7 +613,10 @@ assert.between(0, result, 1); } // Test that the expressions are evaluated once up front. -{ +// +// TODO SERVER-75927: This does not work as expected when the collection is sharded. Once the bug +// is fixed, we should re-enable this test case when the collection is sharded. +if (!isCollSharded) { const values = assert .commandWorked(testDB.runCommand({ find: coll.getName(), |
