summaryrefslogtreecommitdiff
path: root/src/mongo/db/commands/distinct.cpp
diff options
context:
space:
mode:
authorJustin Seyster <justin.seyster@mongodb.com>2019-03-27 19:01:18 -0400
committerJustin Seyster <justin.seyster@mongodb.com>2019-03-28 17:17:27 -0400
commite73da48e26048cb5ca2120acadac2d9c2c8ee403 (patch)
tree1a562334c2cf2bbfc7629f9723439d564c20e847 /src/mongo/db/commands/distinct.cpp
parentb885fa6feb7da00dc367e917c53ba16a41b75af4 (diff)
downloadmongo-e73da48e26048cb5ca2120acadac2d9c2c8ee403.tar.gz
SERVER-40089 $group optimized with DISTINCT_SCAN cannot use $$ROOT
The getExecutorDistinct() function is responsible for both creating an executor for the distinct command and creating an executor for a $group that has been optimized with a DISTINCT_SCAN (see commit da63195). These two scenarios have different requirements for their projection, and getExecutorDistinct() distinguished the two by assuming any caller with an empty ({}) projection wanted the distinct command projection. However, a $first accumulator with $$ROOT requires the entire document, so the logic that builds an optimized $group executor generates an empty projection for this case as well. When that happens, getExecutorDistinct() mistakenly chooses the projection that the distinct command wants, and when the pipeline evaluates $$ROOT, it only gets to see a small subset of fields in the document. This patch modifies getExecutorDistinct() so that the caller must explicitly state what projection it wants. That means that the distinct command no longer passes an empty projection to indicate that it wants to project on just the distinct field. Instead, the distinct command computes the projection for the distinct field on its own and includes that projection in the ParsedDistinct object that it passes to getExecutorDistinct().
Diffstat (limited to 'src/mongo/db/commands/distinct.cpp')
-rw-r--r--src/mongo/db/commands/distinct.cpp12
1 files changed, 8 insertions, 4 deletions
diff --git a/src/mongo/db/commands/distinct.cpp b/src/mongo/db/commands/distinct.cpp
index 9370da8bd73..2f51a659469 100644
--- a/src/mongo/db/commands/distinct.cpp
+++ b/src/mongo/db/commands/distinct.cpp
@@ -127,8 +127,10 @@ public:
const auto nss = ctx->getNss();
const ExtensionsCallbackReal extensionsCallback(opCtx, &nss);
- auto parsedDistinct =
- uassertStatusOK(ParsedDistinct::parse(opCtx, nss, cmdObj, extensionsCallback, true));
+ auto defaultCollator =
+ ctx->getCollection() ? ctx->getCollection()->getDefaultCollator() : nullptr;
+ auto parsedDistinct = uassertStatusOK(
+ ParsedDistinct::parse(opCtx, nss, cmdObj, extensionsCallback, true, defaultCollator));
if (ctx->getView()) {
// Relinquish locks. The aggregation command will re-acquire them.
@@ -179,8 +181,10 @@ public:
const auto& nss = ctx->getNss();
const ExtensionsCallbackReal extensionsCallback(opCtx, &nss);
- auto parsedDistinct =
- uassertStatusOK(ParsedDistinct::parse(opCtx, nss, cmdObj, extensionsCallback, false));
+ auto defaultCollation =
+ ctx->getCollection() ? ctx->getCollection()->getDefaultCollator() : nullptr;
+ auto parsedDistinct = uassertStatusOK(
+ ParsedDistinct::parse(opCtx, nss, cmdObj, extensionsCallback, false, defaultCollation));
// Check whether we are allowed to read from this node after acquiring our locks.
auto replCoord = repl::ReplicationCoordinator::get(opCtx);