diff options
author | Justin Seyster <justin.seyster@mongodb.com> | 2019-03-27 19:01:18 -0400 |
---|---|---|
committer | Justin Seyster <justin.seyster@mongodb.com> | 2019-03-28 17:17:27 -0400 |
commit | e73da48e26048cb5ca2120acadac2d9c2c8ee403 (patch) | |
tree | 1a562334c2cf2bbfc7629f9723439d564c20e847 /src/mongo/db/commands/distinct.cpp | |
parent | b885fa6feb7da00dc367e917c53ba16a41b75af4 (diff) | |
download | mongo-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.cpp | 12 |
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); |