diff options
author | Ian Boros <ian.boros@mongodb.com> | 2020-01-30 13:10:55 -0500 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-02-28 22:16:41 +0000 |
commit | cfa5c05fa1855fb1a04cb3a6e2eb10a7e82bf726 (patch) | |
tree | 7ab1e1ce8e2edd6837952c131fe14d43a0633235 /src/mongo/db/exec/stagedebug_cmd.cpp | |
parent | 793ae32c597f197b6445750aa9bfdaabc206132d (diff) | |
download | mongo-cfa5c05fa1855fb1a04cb3a6e2eb10a7e82bf726.tar.gz |
SERVER-45406 Plumb ExpressionContext through PlanStage
This patch includes also moves ownership of the collator to the ExpressionContext.
Diffstat (limited to 'src/mongo/db/exec/stagedebug_cmd.cpp')
-rw-r--r-- | src/mongo/db/exec/stagedebug_cmd.cpp | 58 |
1 files changed, 31 insertions, 27 deletions
diff --git a/src/mongo/db/exec/stagedebug_cmd.cpp b/src/mongo/db/exec/stagedebug_cmd.cpp index 34190125c51..7baabe4a011 100644 --- a/src/mongo/db/exec/stagedebug_cmd.cpp +++ b/src/mongo/db/exec/stagedebug_cmd.cpp @@ -148,6 +148,9 @@ public: str::stream() << nss.toString() << " is not a valid namespace", nss.isValid()); + auto expCtx = make_intrusive<ExpressionContext>( + opCtx, std::unique_ptr<CollatorInterface>(nullptr), nss); + // Need a context to get the actual Collection* // TODO A write lock is currently taken here to accommodate stages that perform writes // (e.g. DeleteStage). This should be changed to use a read lock for read-only @@ -172,12 +175,12 @@ public: unique_ptr<WorkingSet> ws(new WorkingSet()); std::unique_ptr<PlanStage> userRoot{ - parseQuery(opCtx, collection, planObj, ws.get(), nss, &exprs)}; + parseQuery(expCtx, collection, planObj, ws.get(), nss, &exprs)}; uassert(16911, "Couldn't parse plan from " + cmdObj.toString(), nullptr != userRoot); // Add a fetch at the top for the user so we can get obj back for sure. - unique_ptr<PlanStage> rootFetch = - std::make_unique<FetchStage>(opCtx, ws.get(), std::move(userRoot), nullptr, collection); + unique_ptr<PlanStage> rootFetch = std::make_unique<FetchStage>( + expCtx.get(), ws.get(), std::move(userRoot), nullptr, collection); auto statusWithPlanExecutor = PlanExecutor::make( opCtx, std::move(ws), std::move(rootFetch), collection, PlanExecutor::YIELD_AUTO); @@ -208,12 +211,14 @@ public: return true; } - PlanStage* parseQuery(OperationContext* opCtx, + PlanStage* parseQuery(const boost::intrusive_ptr<ExpressionContext>& expCtx, Collection* collection, BSONObj obj, WorkingSet* workingSet, const NamespaceString& nss, std::vector<std::unique_ptr<MatchExpression>>* exprs) { + OperationContext* opCtx = expCtx->opCtx; + BSONElement firstElt = obj.firstElement(); if (!firstElt.isABSONObj()) { return nullptr; @@ -235,9 +240,6 @@ public: } BSONObj argObj = e.Obj(); if (filterTag == e.fieldName()) { - const CollatorInterface* collator = nullptr; - const boost::intrusive_ptr<ExpressionContext> expCtx( - new ExpressionContext(opCtx, collator, nss)); auto statusWithMatcher = MatchExpressionParser::parse(argObj, expCtx, @@ -299,12 +301,12 @@ public: params.direction = nodeArgs["direction"].numberInt(); params.shouldDedup = desc->isMultikey(); - return new IndexScan(opCtx, params, workingSet, matcher); + return new IndexScan(expCtx.get(), params, workingSet, matcher); } else if ("andHash" == nodeName) { uassert( 16921, "Nodes argument must be provided to AND", nodeArgs["nodes"].isABSONObj()); - auto andStage = std::make_unique<AndHashStage>(opCtx, workingSet); + auto andStage = std::make_unique<AndHashStage>(expCtx.get(), workingSet); int nodesAdded = 0; BSONObjIterator it(nodeArgs["nodes"].Obj()); @@ -313,7 +315,7 @@ public: uassert(16922, "node of AND isn't an obj?: " + e.toString(), e.isABSONObj()); std::unique_ptr<PlanStage> subNode{ - parseQuery(opCtx, collection, e.Obj(), workingSet, nss, exprs)}; + parseQuery(expCtx, collection, e.Obj(), workingSet, nss, exprs)}; uassert(16923, "Can't parse sub-node of AND: " + e.Obj().toString(), nullptr != subNode); @@ -328,7 +330,7 @@ public: uassert( 16924, "Nodes argument must be provided to AND", nodeArgs["nodes"].isABSONObj()); - auto andStage = std::make_unique<AndSortedStage>(opCtx, workingSet); + auto andStage = std::make_unique<AndSortedStage>(expCtx.get(), workingSet); int nodesAdded = 0; BSONObjIterator it(nodeArgs["nodes"].Obj()); @@ -337,7 +339,7 @@ public: uassert(16925, "node of AND isn't an obj?: " + e.toString(), e.isABSONObj()); std::unique_ptr<PlanStage> subNode{ - parseQuery(opCtx, collection, e.Obj(), workingSet, nss, exprs)}; + parseQuery(expCtx, collection, e.Obj(), workingSet, nss, exprs)}; uassert(16926, "Can't parse sub-node of AND: " + e.Obj().toString(), nullptr != subNode); @@ -353,15 +355,15 @@ public: 16934, "Nodes argument must be provided to AND", nodeArgs["nodes"].isABSONObj()); uassert(16935, "Dedup argument must be provided to OR", !nodeArgs["dedup"].eoo()); BSONObjIterator it(nodeArgs["nodes"].Obj()); - auto orStage = - std::make_unique<OrStage>(opCtx, workingSet, nodeArgs["dedup"].Bool(), matcher); + auto orStage = std::make_unique<OrStage>( + expCtx.get(), workingSet, nodeArgs["dedup"].Bool(), matcher); while (it.more()) { BSONElement e = it.next(); if (!e.isABSONObj()) { return nullptr; } std::unique_ptr<PlanStage> subNode{ - parseQuery(opCtx, collection, e.Obj(), workingSet, nss, exprs)}; + parseQuery(expCtx, collection, e.Obj(), workingSet, nss, exprs)}; uassert( 16936, "Can't parse sub-node of OR: " + e.Obj().toString(), nullptr != subNode); orStage->addChild(std::move(subNode)); @@ -372,11 +374,12 @@ public: uassert( 16929, "Node argument must be provided to fetch", nodeArgs["node"].isABSONObj()); std::unique_ptr<PlanStage> subNode{ - parseQuery(opCtx, collection, nodeArgs["node"].Obj(), workingSet, nss, exprs)}; + parseQuery(expCtx, collection, nodeArgs["node"].Obj(), workingSet, nss, exprs)}; uassert(28731, "Can't parse sub-node of FETCH: " + nodeArgs["node"].Obj().toString(), nullptr != subNode); - return new FetchStage(opCtx, workingSet, std::move(subNode), matcher, collection); + return new FetchStage( + expCtx.get(), workingSet, std::move(subNode), matcher, collection); } else if ("limit" == nodeName) { uassert(16937, "Limit stage doesn't have a filter (put it on the child)", @@ -385,12 +388,12 @@ public: 16930, "Node argument must be provided to limit", nodeArgs["node"].isABSONObj()); uassert(16931, "Num argument must be provided to limit", nodeArgs["num"].isNumber()); std::unique_ptr<PlanStage> subNode{ - parseQuery(opCtx, collection, nodeArgs["node"].Obj(), workingSet, nss, exprs)}; + parseQuery(expCtx, collection, nodeArgs["node"].Obj(), workingSet, nss, exprs)}; uassert(28732, "Can't parse sub-node of LIMIT: " + nodeArgs["node"].Obj().toString(), nullptr != subNode); return new LimitStage( - opCtx, nodeArgs["num"].numberInt(), workingSet, std ::move(subNode)); + expCtx.get(), nodeArgs["num"].numberInt(), workingSet, std ::move(subNode)); } else if ("skip" == nodeName) { uassert(16938, "Skip stage doesn't have a filter (put it on the child)", @@ -398,12 +401,12 @@ public: uassert(16932, "Node argument must be provided to skip", nodeArgs["node"].isABSONObj()); uassert(16933, "Num argument must be provided to skip", nodeArgs["num"].isNumber()); std::unique_ptr<PlanStage> subNode{ - parseQuery(opCtx, collection, nodeArgs["node"].Obj(), workingSet, nss, exprs)}; + parseQuery(expCtx, collection, nodeArgs["node"].Obj(), workingSet, nss, exprs)}; uassert(28733, "Can't parse sub-node of SKIP: " + nodeArgs["node"].Obj().toString(), nullptr != subNode); return new SkipStage( - opCtx, nodeArgs["num"].numberInt(), workingSet, std::move(subNode)); + expCtx.get(), nodeArgs["num"].numberInt(), workingSet, std::move(subNode)); } else if ("cscan" == nodeName) { CollectionScanParams params; @@ -417,7 +420,7 @@ public: params.direction = CollectionScanParams::BACKWARD; } - return new CollectionScan(opCtx, collection, params, workingSet, matcher); + return new CollectionScan(expCtx.get(), collection, params, workingSet, matcher); } else if ("mergeSort" == nodeName) { uassert( 16971, "Nodes argument must be provided to sort", nodeArgs["nodes"].isABSONObj()); @@ -429,7 +432,7 @@ public: params.pattern = nodeArgs["pattern"].Obj(); // Dedup is true by default. - auto mergeStage = std::make_unique<MergeSortStage>(opCtx, params, workingSet); + auto mergeStage = std::make_unique<MergeSortStage>(expCtx.get(), params, workingSet); BSONObjIterator it(nodeArgs["nodes"].Obj()); while (it.more()) { @@ -437,7 +440,7 @@ public: uassert(16973, "node of mergeSort isn't an obj?: " + e.toString(), e.isABSONObj()); std::unique_ptr<PlanStage> subNode{ - parseQuery(opCtx, collection, e.Obj(), workingSet, nss, exprs)}; + parseQuery(expCtx, collection, e.Obj(), workingSet, nss, exprs)}; uassert(16974, "Can't parse sub-node of mergeSort: " + e.Obj().toString(), nullptr != subNode); @@ -475,7 +478,7 @@ public: return nullptr; } - return new TextStage(opCtx, params, workingSet, matcher); + return new TextStage(expCtx.get(), params, workingSet, matcher); } else if ("delete" == nodeName) { uassert(18636, "Delete stage doesn't have a filter (put it on the child)", @@ -486,13 +489,14 @@ public: "isMulti argument must be provided to delete", nodeArgs["isMulti"].type() == Bool); PlanStage* subNode = - parseQuery(opCtx, collection, nodeArgs["node"].Obj(), workingSet, nss, exprs); + parseQuery(expCtx, collection, nodeArgs["node"].Obj(), workingSet, nss, exprs); uassert(28734, "Can't parse sub-node of DELETE: " + nodeArgs["node"].Obj().toString(), nullptr != subNode); auto params = std::make_unique<DeleteStageParams>(); params->isMulti = nodeArgs["isMulti"].Bool(); - return new DeleteStage(opCtx, std::move(params), workingSet, collection, subNode); + return new DeleteStage( + expCtx.get(), std::move(params), workingSet, collection, subNode); } else { return nullptr; } |