diff options
author | Benjamin Murphy <benjamin_murphy@me.com> | 2016-01-27 16:42:04 -0500 |
---|---|---|
committer | Benjamin Murphy <benjamin_murphy@me.com> | 2016-02-08 12:53:48 -0500 |
commit | c3a232ef38480f317cd42cc00755fd9032c107d2 (patch) | |
tree | bb664b92f2ffcf1b6c9c1dab0ad483404ac7d813 | |
parent | a1a4f91a9c70b3f9f58f2922c260f1df97418e2c (diff) | |
download | mongo-c3a232ef38480f317cd42cc00755fd9032c107d2.tar.gz |
SERVER-19643 Aggregation directly from a shard does not use sharding filter.
-rw-r--r-- | jstests/aggregation/testshard1.js | 11 | ||||
-rw-r--r-- | src/mongo/db/commands/pipeline_command.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/pipeline/pipeline_d.cpp | 23 | ||||
-rw-r--r-- | src/mongo/db/pipeline/pipeline_d.h | 3 |
4 files changed, 34 insertions, 5 deletions
diff --git a/jstests/aggregation/testshard1.js b/jstests/aggregation/testshard1.js index 64cc46ffaa6..ef9f91bae70 100644 --- a/jstests/aggregation/testshard1.js +++ b/jstests/aggregation/testshard1.js @@ -1,4 +1,5 @@ load('jstests/aggregation/extras/utils.js'); +load('jstests/libs/analyze_plan.js'); // For planHasStage. // Use this for aggregations that only have arrays or results of specified order. // It will check that cursors return the same results as non-cursors. @@ -267,6 +268,16 @@ for (var shardName in res.shards) { } (function() { + jsTestLog("Do a sharded explain from a mongod, not mongos, to ensure that it does not have " + + "a SHARDING_FILTER stage."); + var shardDb = shardedAggTest.shard0.getDB('aggShard'); + var res = shardDb.ts1.aggregate([{$match: {}}], {explain: true}); + printjson(res); + assert.commandWorked(res); + assert(!planHasStage(res.stages[0].$cursor.queryPlanner.winningPlan, "SHARDING_FILTER")); +}()); + +(function() { jsTestLog('Testing a $match stage on the shard key.'); var outCollection = 'testShardKeyMatchOut'; diff --git a/src/mongo/db/commands/pipeline_command.cpp b/src/mongo/db/commands/pipeline_command.cpp index fc3537d1a49..31b80d4fda6 100644 --- a/src/mongo/db/commands/pipeline_command.cpp +++ b/src/mongo/db/commands/pipeline_command.cpp @@ -224,7 +224,7 @@ public: // This does mongod-specific stuff like creating the input PlanExecutor and adding // it to the front of the pipeline if needed. std::shared_ptr<PlanExecutor> input = - PipelineD::prepareCursorSource(txn, collection, pPipeline, pCtx); + PipelineD::prepareCursorSource(txn, collection, nss, pPipeline, pCtx); pPipeline->stitch(); if (collection && input) { diff --git a/src/mongo/db/pipeline/pipeline_d.cpp b/src/mongo/db/pipeline/pipeline_d.cpp index 06114c90404..4cebf691c26 100644 --- a/src/mongo/db/pipeline/pipeline_d.cpp +++ b/src/mongo/db/pipeline/pipeline_d.cpp @@ -214,6 +214,7 @@ StatusWith<std::unique_ptr<PlanExecutor>> attemptToGetExecutor( shared_ptr<PlanExecutor> PipelineD::prepareCursorSource( OperationContext* txn, Collection* collection, + const NamespaceString& nss, const intrusive_ptr<Pipeline>& pPipeline, const intrusive_ptr<ExpressionContext>& pExpCtx) { // We will be modifying the source vector as we go. @@ -292,8 +293,16 @@ shared_ptr<PlanExecutor> PipelineD::prepareCursorSource( } // Create the PlanExecutor. - auto exec = prepareExecutor( - txn, collection, pPipeline, pExpCtx, sortStage, deps, queryObj, &sortObj, &projForQuery); + auto exec = prepareExecutor(txn, + collection, + nss, + pPipeline, + pExpCtx, + sortStage, + deps, + queryObj, + &sortObj, + &projForQuery); return addCursorSource(pPipeline, pExpCtx, exec, deps, queryObj, sortObj, projForQuery); } @@ -301,6 +310,7 @@ shared_ptr<PlanExecutor> PipelineD::prepareCursorSource( std::shared_ptr<PlanExecutor> PipelineD::prepareExecutor( OperationContext* txn, Collection* collection, + const NamespaceString& nss, const intrusive_ptr<Pipeline>& pipeline, const intrusive_ptr<ExpressionContext>& expCtx, const intrusive_ptr<DocumentSourceSort>& sortStage, @@ -326,8 +336,13 @@ std::shared_ptr<PlanExecutor> PipelineD::prepareExecutor( // // LATER - We should attempt to determine if the results from the query are returned in some // order so we can then apply other optimizations there are tickets for, such as SERVER-4507. - size_t plannerOpts = QueryPlannerParams::DEFAULT | QueryPlannerParams::INCLUDE_SHARD_FILTER | - QueryPlannerParams::NO_BLOCKING_SORT; + size_t plannerOpts = QueryPlannerParams::DEFAULT | QueryPlannerParams::NO_BLOCKING_SORT; + + // If we are connecting directly to the shard rather than through a mongos, don't filter out + // orphaned documents. + if (ShardingState::get(txn)->needCollectionMetadata(txn, nss.ns())) { + plannerOpts |= QueryPlannerParams::INCLUDE_SHARD_FILTER; + } // The only way to get a text score is to let the query system handle the projection. In all // other cases, unless the query system can do an index-covered projection and avoid going to diff --git a/src/mongo/db/pipeline/pipeline_d.h b/src/mongo/db/pipeline/pipeline_d.h index a9993c6331b..95a08719b41 100644 --- a/src/mongo/db/pipeline/pipeline_d.h +++ b/src/mongo/db/pipeline/pipeline_d.h @@ -32,6 +32,7 @@ #include <memory> #include "mongo/bson/bsonobj.h" +#include "mongo/db/namespace_string.h" namespace mongo { class Collection; @@ -79,6 +80,7 @@ public: static std::shared_ptr<PlanExecutor> prepareCursorSource( OperationContext* txn, Collection* collection, + const NamespaceString& nss, const boost::intrusive_ptr<Pipeline>& pPipeline, const boost::intrusive_ptr<ExpressionContext>& pExpCtx); @@ -97,6 +99,7 @@ private: static std::shared_ptr<PlanExecutor> prepareExecutor( OperationContext* txn, Collection* collection, + const NamespaceString& nss, const boost::intrusive_ptr<Pipeline>& pipeline, const boost::intrusive_ptr<ExpressionContext>& expCtx, const boost::intrusive_ptr<DocumentSourceSort>& sortStage, |