summaryrefslogtreecommitdiff
path: root/src/mongo/db/query/planner_access.cpp
diff options
context:
space:
mode:
authorDavid Storch <david.storch@10gen.com>2014-03-27 11:18:09 -0400
committerDavid Storch <david.storch@10gen.com>2014-03-27 17:14:39 -0400
commit719134aa7985c0a697f199fc78e323d04e3a65ad (patch)
tree7f420eb21e239de3565d4f66fbe974bb20191083 /src/mongo/db/query/planner_access.cpp
parent2850ecc726d6ef33ff4284e1ce0378fb42d3b854 (diff)
downloadmongo-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.cpp38
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;