diff options
author | David Storch <david.storch@10gen.com> | 2014-03-27 11:18:09 -0400 |
---|---|---|
committer | David Storch <david.storch@10gen.com> | 2014-03-27 17:14:39 -0400 |
commit | 719134aa7985c0a697f199fc78e323d04e3a65ad (patch) | |
tree | 7f420eb21e239de3565d4f66fbe974bb20191083 /src/mongo/db/query/planner_access.cpp | |
parent | 2850ecc726d6ef33ff4284e1ce0378fb42d3b854 (diff) | |
download | mongo-719134aa7985c0a697f199fc78e323d04e3a65ad.tar.gz |
SERVER-13205 fix merging of special leaf nodes in access planner
Diffstat (limited to 'src/mongo/db/query/planner_access.cpp')
-rw-r--r-- | src/mongo/db/query/planner_access.cpp | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/src/mongo/db/query/planner_access.cpp b/src/mongo/db/query/planner_access.cpp index 92387fd26af..84082d0fcb8 100644 --- a/src/mongo/db/query/planner_access.cpp +++ b/src/mongo/db/query/planner_access.cpp @@ -184,11 +184,43 @@ namespace mongo { const StageType type = node->getType(); verify(STAGE_GEO_NEAR_2D != type); - if (STAGE_GEO_2D == type || STAGE_TEXT == type || - STAGE_GEO_NEAR_2DSPHERE == type) { - return true; + const MatchExpression::MatchType exprType = expr->matchType(); + + // + // First handle special solution tree leaf types. In general, normal index bounds + // building is not used for special leaf types, and hence we cannot merge leaves. + // + // This rule is always true for OR, but there are exceptions for AND. + // Specifically, we can often merge a predicate with a special leaf type + // by adding a filter to the special leaf type. + // + + if (STAGE_GEO_2D == type) { + // Don't merge GEO with a geo leaf. Instead, we will generate an AND_HASH solution + // with two separate leaves. + return MatchExpression::AND == mergeType + && MatchExpression::GEO != exprType; + } + + if (STAGE_TEXT == type) { + // Currently only one text predicate is allowed, but to be safe, make sure that we + // do not try to merge two text predicates. + return MatchExpression::AND == mergeType + && MatchExpression::TEXT != exprType; + } + + if (STAGE_GEO_NEAR_2DSPHERE == type) { + // Currently only one GEO_NEAR is allowed, but to be safe, make sure that we + // do not try to merge two GEO_NEAR predicates. + return MatchExpression::AND == mergeType + && MatchExpression::GEO_NEAR != exprType; } + // + // If we're here, then we're done checking for special leaf nodes, and the leaf + // must be a regular index scan. + // + invariant(type == STAGE_IXSCAN); IndexScanNode* scan = static_cast<IndexScanNode*>(node); IndexBounds* boundsToFillOut = &scan->bounds; |