diff options
Diffstat (limited to 'src/mongo/db/commands')
-rw-r--r-- | src/mongo/db/commands/find_cmd.cpp | 11 | ||||
-rw-r--r-- | src/mongo/db/commands/getmore_cmd.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/commands/run_aggregate.cpp | 29 |
3 files changed, 40 insertions, 4 deletions
diff --git a/src/mongo/db/commands/find_cmd.cpp b/src/mongo/db/commands/find_cmd.cpp index 7102a2c8840..8c1e299fdb1 100644 --- a/src/mongo/db/commands/find_cmd.cpp +++ b/src/mongo/db/commands/find_cmd.cpp @@ -115,6 +115,17 @@ boost::intrusive_ptr<ExpressionContext> makeExpressionContext( boost::none // uuid ); expCtx->tempDir = storageGlobalParams.dbpath + "/_tmp"; + // TODO (SERVER-43361): We will not need to set 'sortKeyFormat' after branching for 4.5. + auto assumeInternalClient = !opCtx->getClient()->session() || + (opCtx->getClient()->session()->getTags() & transport::Session::kInternalClient); + if (assumeInternalClient) { + expCtx->sortKeyFormat = + queryRequest.use44SortKeys() ? SortKeyFormat::k44SortKey : SortKeyFormat::k42SortKey; + } else { + // The client is not a mongoS, so we will not need to use an older sort key format to + // support it. Use default value for the ExpressionContext's 'sortKeyFormat' member + // variable, which is the newest format. + } return expCtx; } diff --git a/src/mongo/db/commands/getmore_cmd.cpp b/src/mongo/db/commands/getmore_cmd.cpp index 687e5e32de8..d0129eaba5c 100644 --- a/src/mongo/db/commands/getmore_cmd.cpp +++ b/src/mongo/db/commands/getmore_cmd.cpp @@ -295,8 +295,10 @@ public: while (!FindCommon::enoughForGetMore(request.batchSize.value_or(0), *numResults) && PlanExecutor::ADVANCED == (*state = exec->getNext(&doc, nullptr))) { auto* expCtx = exec->getExpCtx().get(); + // Note that "needsMerge" implies a find or aggregate operation, which should + // always have a non-NULL 'expCtx' value. BSONObj obj = cursor->needsMerge() - ? doc.toBsonWithMetaData(expCtx ? expCtx->use42ChangeStreamSortKeys : false) + ? doc.toBsonWithMetaData(expCtx->sortKeyFormat) : doc.toBson(); // If adding this object will cause us to exceed the message size limit, then we diff --git a/src/mongo/db/commands/run_aggregate.cpp b/src/mongo/db/commands/run_aggregate.cpp index 8569562dd1d..283e5516991 100644 --- a/src/mongo/db/commands/run_aggregate.cpp +++ b/src/mongo/db/commands/run_aggregate.cpp @@ -214,9 +214,8 @@ bool handleCursorCommand(OperationContext* opCtx, // for later. auto* expCtx = exec->getExpCtx().get(); - BSONObj next = expCtx->needsMerge - ? nextDoc.toBsonWithMetaData(expCtx ? expCtx->use42ChangeStreamSortKeys : false) - : nextDoc.toBson(); + BSONObj next = expCtx->needsMerge ? nextDoc.toBsonWithMetaData(expCtx->sortKeyFormat) + : nextDoc.toBson(); if (!FindCommon::haveSpaceForNext(next, objCount, responseBuilder.bytesUsed())) { exec->enqueue(nextDoc); stashedResult = true; @@ -618,6 +617,30 @@ Status runAggregate(OperationContext* opCtx, invariant(collatorToUse); expCtx = makeExpressionContext(opCtx, request, std::move(*collatorToUse), uuid); + // If this is a shard server, we need to use the correct sort key format for the mongoS that + // generated this query. We determine the version by checking for the "use44SortKeys" flag + // in the aggregation request. + // TODO (SERVER-43361): This check will be unnecessary after branching for 4.5. + if (expCtx->fromMongos) { + if (request.getUse44SortKeys()) { + // This request originated with 4.4-or-newer mongoS, which can understand the new + // sort key format. Note: it's possible that merging will actually occur on a mongoD + // (for pipelines that merge on a shard), but if the mongoS is 4.4 or newer, all + // shard servers must also be 4.4 or newer. + expCtx->sortKeyFormat = SortKeyFormat::k44SortKey; + } else { + // This request originated with an older mongoS that will not understand the new + // sort key format. We must use the older format, which differs depending on whether + // or not the pipeline is a change stream. Non-$changeStream pipelines may still + // merge on a mongoD, but a 4.4 mongoD can still understand the 4.2 sort key format. + expCtx->sortKeyFormat = liteParsedPipeline.hasChangeStream() + ? SortKeyFormat::k42ChangeStreamSortKey + : SortKeyFormat::k42SortKey; + } + } else { + // Use default value for the ExpressionContext's 'sortKeyFormat' member variable. + } + auto pipeline = uassertStatusOK(Pipeline::parse(request.getPipeline(), expCtx)); // Check that the view's collation matches the collation of any views involved in the |