summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorDavid Storch <david.storch@10gen.com>2017-12-06 12:28:16 -0500
committerDavid Storch <david.storch@10gen.com>2017-12-13 16:01:07 -0500
commit1e0d2b2e113df9e56af430f5ff09bac224cf05f0 (patch)
tree8d96bbb45a8e8d21408e911038a78728816eb30c /src/mongo/db
parent06c1da7fa0d99fe643674fa7d5b0533b7d364791 (diff)
downloadmongo-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.cpp67
-rw-r--r--src/mongo/db/exec/subplan.h13
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.
//