diff options
author | David Storch <david.storch@10gen.com> | 2017-12-06 12:28:16 -0500 |
---|---|---|
committer | David Storch <david.storch@10gen.com> | 2017-12-13 16:01:07 -0500 |
commit | 1e0d2b2e113df9e56af430f5ff09bac224cf05f0 (patch) | |
tree | 8d96bbb45a8e8d21408e911038a78728816eb30c /src/mongo/db | |
parent | 06c1da7fa0d99fe643674fa7d5b0533b7d364791 (diff) | |
download | mongo-1e0d2b2e113df9e56af430f5ff09bac224cf05f0.tar.gz |
SERVER-32189 Delete dead SubplanStage handling for contained $or queries.
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/exec/subplan.cpp | 67 | ||||
-rw-r--r-- | src/mongo/db/exec/subplan.h | 13 |
2 files changed, 2 insertions, 78 deletions
diff --git a/src/mongo/db/exec/subplan.cpp b/src/mongo/db/exec/subplan.cpp index f8b30a6a7a3..0d3ee99ffc4 100644 --- a/src/mongo/db/exec/subplan.cpp +++ b/src/mongo/db/exec/subplan.cpp @@ -71,30 +71,9 @@ SubplanStage::SubplanStage(OperationContext* opCtx, _plannerParams(params), _query(cq) { invariant(_collection); + invariant(_query->root()->matchType() == MatchExpression::OR); } -namespace { - -/** - * Returns true if 'expr' is an AND that contains a single OR child. - */ -bool isContainedOr(const MatchExpression* expr) { - if (MatchExpression::AND != expr->matchType()) { - return false; - } - - size_t numOrs = 0; - for (size_t i = 0; i < expr->numChildren(); ++i) { - if (MatchExpression::OR == expr->getChild(i)->matchType()) { - ++numOrs; - } - } - - return (numOrs == 1U); -} - -} // namespace - bool SubplanStage::canUseSubplanning(const CanonicalQuery& query) { const QueryRequest& qr = query.getQueryRequest(); const MatchExpression* expr = query.root(); @@ -126,54 +105,12 @@ bool SubplanStage::canUseSubplanning(const CanonicalQuery& query) { return false; } - // TODO: For now we only allow rooted OR. We should consider also allowing contained OR that - // does not have a TEXT or GEO_NEAR node. + // We can only subplan rooted $or queries. return MatchExpression::OR == expr->matchType(); } -std::unique_ptr<MatchExpression> SubplanStage::rewriteToRootedOr( - std::unique_ptr<MatchExpression> root) { - dassert(isContainedOr(root.get())); - - // Detach the OR from the root. - std::vector<MatchExpression*>& rootChildren = *root->getChildVector(); - std::unique_ptr<MatchExpression> orChild; - for (size_t i = 0; i < rootChildren.size(); ++i) { - if (MatchExpression::OR == rootChildren[i]->matchType()) { - orChild.reset(rootChildren[i]); - rootChildren.erase(rootChildren.begin() + i); - break; - } - } - - // We should have found an OR, and the OR should have at least 2 children. - invariant(orChild); - invariant(orChild->getChildVector()); - invariant(orChild->getChildVector()->size() > 1U); - - // AND the existing root with each OR child. - std::vector<MatchExpression*>& orChildren = *orChild->getChildVector(); - for (size_t i = 0; i < orChildren.size(); ++i) { - std::unique_ptr<AndMatchExpression> ama = stdx::make_unique<AndMatchExpression>(); - ama->add(orChildren[i]); - ama->add(root->shallowClone().release()); - orChildren[i] = ama.release(); - } - - // Normalize and sort the resulting match expression. - orChild = MatchExpression::optimize(std::move(orChild)); - CanonicalQuery::sortTree(orChild.get()); - - return orChild; -} - Status SubplanStage::planSubqueries() { _orExpression = _query->root()->shallowClone(); - if (isContainedOr(_orExpression.get())) { - _orExpression = rewriteToRootedOr(std::move(_orExpression)); - invariant(CanonicalQuery::isValid(_orExpression.get(), _query->getQueryRequest()).isOK()); - } - for (size_t i = 0; i < _plannerParams.indices.size(); ++i) { const IndexEntry& ie = _plannerParams.indices[i]; _indexMap[ie.name] = i; diff --git a/src/mongo/db/exec/subplan.h b/src/mongo/db/exec/subplan.h index 315e79b93ca..c61fb3201d4 100644 --- a/src/mongo/db/exec/subplan.h +++ b/src/mongo/db/exec/subplan.h @@ -107,19 +107,6 @@ public: */ Status pickBestPlan(PlanYieldPolicy* yieldPolicy); - /** - * Takes a match expression, 'root', which has a single "contained OR". This means that - * 'root' is an AND with exactly one OR child. - * - * Returns a logically equivalent query after rewriting so that the contained OR is at the - * root of the expression tree. - * - * Used internally so that the subplanner can be used for contained OR type queries, but - * exposed for testing. - */ - static std::unique_ptr<MatchExpression> rewriteToRootedOr( - std::unique_ptr<MatchExpression> root); - // // For testing. // |