diff --git a/jstests/core/administrative/getlog2.js b/jstests/core/administrative/getlog2.js index 8f671aaeb7d..5808d228b6c 100644 --- a/jstests/core/administrative/getlog2.js +++ b/jstests/core/administrative/getlog2.js @@ -12,8 +12,6 @@ // requires_profiling, // # Uses $where operation. // requires_scripting, -// # TODO SERVER-112352 Re-parse error when using $where in an update -// known_query_shape_computation_problem, // ] // We turn off gossiping the mongo shell's clusterTime because it causes the slow command log diff --git a/src/mongo/db/query/query_shape/update_cmd_shape.cpp b/src/mongo/db/query/query_shape/update_cmd_shape.cpp index dce3c205035..476df3db12c 100644 --- a/src/mongo/db/query/query_shape/update_cmd_shape.cpp +++ b/src/mongo/db/query/query_shape/update_cmd_shape.cpp @@ -32,6 +32,7 @@ #include "mongo/bson/bsonelement.h" #include "mongo/bson/bsonobj.h" #include "mongo/bson/bsonobjbuilder.h" +#include "mongo/db/matcher/extensions_callback_noop.h" #include "mongo/db/pipeline/expression_context_builder.h" #include "mongo/db/query/query_shape/let_shape_component.h" #include "mongo/db/query/query_shape/serialization_options.h" @@ -228,9 +229,7 @@ void UpdateCmdShape::appendCmdSpecificShapeComponents(BSONObjBuilder& bob, } auto parsedUpdate = uassertStatusOK(parsed_update_command::parse( - expCtx, - &updateRequest, - makeExtensionsCallback(opCtx, &updateRequest.getNsString()))); + expCtx, &updateRequest, makeExtensionsCallback())); UpdateCmdShapeComponents{parsedUpdate, _components.let, opts}.appendTo(bob, opts, expCtx); } diff --git a/src/mongo/db/query/query_shape/update_cmd_shape_test.cpp b/src/mongo/db/query/query_shape/update_cmd_shape_test.cpp index ec1593e71c5..04f1cb5ce83 100644 --- a/src/mongo/db/query/query_shape/update_cmd_shape_test.cpp +++ b/src/mongo/db/query/query_shape/update_cmd_shape_test.cpp @@ -30,6 +30,7 @@ #include "mongo/db/query/query_shape/update_cmd_shape.h" #include "mongo/bson/json.h" +#include "mongo/db/matcher/extensions_callback_noop.h" #include "mongo/db/pipeline/expression_context_for_test.h" #include "mongo/db/query/query_shape/let_shape_component.h" #include "mongo/db/query/query_shape/update_cmd_builder.h" @@ -53,11 +54,15 @@ public: _expCtx = make_intrusive(); } - std::vector makeShapesFromUpdate(StringData updateCmd) { - auto updateRequest = UpdateCommandRequest::parseOwned(fromjson(updateCmd)); + std::vector makeShapesFromUpdate(BSONObj updateCmd) { + auto updateRequest = UpdateCommandRequest::parseOwned(std::move(updateCmd)); return makeShapesFromUpdateRequest(updateRequest); } + std::vector makeShapesFromUpdate(StringData updateCmd) { + return makeShapesFromUpdate(fromjson(updateCmd)); + } + std::vector makeShapesFromUpdateRequest( const write_ops::UpdateCommandRequest& updateRequest) { std::vector shapes; @@ -71,17 +76,16 @@ public: _expCtx = makeBlankExpressionContext( _operationContext.get(), updateRequest.getNamespace(), updateRequest.getLet()); - auto parsedUpdate = uassertStatusOK( - parsed_update_command::parse(_expCtx, - &request, - makeExtensionsCallback( - _operationContext.get(), &request.getNsString()))); + auto parsedUpdate = uassertStatusOK(parsed_update_command::parse( + _expCtx, &request, makeExtensionsCallback())); shapes.emplace_back(updateRequest, parsedUpdate, _expCtx); } return shapes; } - UpdateCmdShape makeOneShapeFromUpdate(StringData updateCmd) { + template + requires std::is_same_v || std::is_same_v + UpdateCmdShape makeOneShapeFromUpdate(T updateCmd) { auto shapes = makeShapesFromUpdate(updateCmd); ASSERT_EQ(shapes.size(), 1); return shapes.front(); @@ -1536,6 +1540,53 @@ TEST_F(UpdateCmdShapeTest, PipelineUpdateWithStageAliasesShape) { SerializationContext::stateDefault())); } +TEST_F(UpdateCmdShapeTest, WhereUpdateShape) { + auto cmd = BSON( + "update" << "testColl" << "updates" + << BSON_ARRAY(BSON( + "q" << BSON("$where" << BSONCode("function(){ sleep(1000); return true;}")) + << "u" << BSON("$set" << BSON("item" << "ABC123")))) + << "$db" << "testDB"); + auto shape = makeOneShapeFromUpdate(cmd); + + ASSERT_BSONOBJ_EQ( // NOLINT + BSON("cmdNs" << BSON("db" << "testDB" << "coll" << "testColl") << "command" << "update" + << "q" << BSON("$where" << BSONCode("return ?;")) << "u" + << BSON("$set" << BSON("item" << "?")) << "multi" << false << "upsert" + << false), + shape.toBson(_operationContext.get(), + SerializationOptions::kRepresentativeQueryShapeSerializeOptions, + SerializationContext::stateDefault())); + ASSERT_BSONOBJ_EQ_AUTO( // NOLINT + R"({ + cmdNs: { + db: "testDB", + coll: "testColl" + }, + command: "update", + q: { $where: "?javascript" }, + u: { $set: { item: "?string" } }, + multi: false, + upsert: false })", + shape.toBson(_operationContext.get(), + SerializationOptions::kDebugQueryShapeSerializeOptions, + SerializationContext::stateDefault())); + ASSERT_BSONOBJ_EQ_AUTO( // NOLINT + R"({ + cmdNs: { + db: "HASH", + coll: "HASH" + }, + command: "update", + q: { $where: "?javascript" }, + u: { $set: { "HASH": "?string" } }, + multi: false, + upsert: false })", + shape.toBson(_operationContext.get(), + SerializationOptions::kDebugShapeAndMarkIdentifiers_FOR_TEST, + SerializationContext::stateDefault())); +} + TEST_F(UpdateCmdShapeTest, BatchReplacementUpdateShape) { auto shapes = makeShapesFromUpdate(R"({ update: "testColl",