summaryrefslogtreecommitdiff
path: root/src/mongo/db/query
diff options
context:
space:
mode:
authorDavid Storch <david.storch@10gen.com>2014-06-05 19:00:41 -0400
committerDavid Storch <david.storch@10gen.com>2014-06-06 09:38:53 -0400
commit2453cec627bb8f6100980dea273ac9eb54ecd645 (patch)
tree8270e6d297add97c7f72338220b88871227020af /src/mongo/db/query
parentffaa85ae89335efbef26338a12cc41b351fc8bda (diff)
downloadmongo-2453cec627bb8f6100980dea273ac9eb54ecd645.tar.gz
SERVER-14180 fix double free in access planning for $elemMatch
Diffstat (limited to 'src/mongo/db/query')
-rw-r--r--src/mongo/db/query/planner_access.cpp20
-rw-r--r--src/mongo/db/query/query_planner_test.cpp22
2 files changed, 22 insertions, 20 deletions
diff --git a/src/mongo/db/query/planner_access.cpp b/src/mongo/db/query/planner_access.cpp
index 734cb2f9984..705f25d6aad 100644
--- a/src/mongo/db/query/planner_access.cpp
+++ b/src/mongo/db/query/planner_access.cpp
@@ -737,16 +737,6 @@ namespace mongo {
scanState->tightness = IndexBoundsBuilder::INEXACT_FETCH;
mergeWithLeafNode(emChild, scanState);
-
- if (scanState->tightness == IndexBoundsBuilder::INEXACT_COVERED
- && !indices[scanState->currentIndexNumber].multikey) {
- // Add the filter to the current index scan. This is optional because
- // the entire filter will get affixed to the parent AND. It is here
- // as an optimization---an additional filter during the index scan
- // stage will cause fewer documents to bubble up to the parent node
- // of the execution tree.
- addFilterToSolutionNode(scanState->currentScan.get(), emChild, root->matchType());
- }
}
else {
if (NULL != scanState->currentScan.get()) {
@@ -762,16 +752,6 @@ namespace mongo {
scanState->currentScan.reset(makeLeafNode(query, indices[scanState->currentIndexNumber],
scanState->ixtag->pos,
emChild, &scanState->tightness));
-
- if (scanState->tightness == IndexBoundsBuilder::INEXACT_COVERED
- && !indices[scanState->currentIndexNumber].multikey) {
- // Add the filter to the current index scan. This is optional because
- // the entire filter will get affixed to the parent AND. It is here
- // as an optimization---an additional filter during the index scan
- // stage will cause fewer documents to bubble up to the parent node
- // of the execution tree.
- addFilterToSolutionNode(scanState->currentScan.get(), emChild, root->matchType());
- }
}
}
diff --git a/src/mongo/db/query/query_planner_test.cpp b/src/mongo/db/query/query_planner_test.cpp
index 4fdd393c0d9..29648c77598 100644
--- a/src/mongo/db/query/query_planner_test.cpp
+++ b/src/mongo/db/query/query_planner_test.cpp
@@ -1612,6 +1612,28 @@ namespace {
"{ixscan: {filter: null, pattern: {'a.b': 1}}}}}");
}
+ // SERVER-14180
+ TEST_F(QueryPlannerTest, ElemMatchEmbeddedRegexAnd) {
+ addIndex(BSON("a.b" << 1));
+ runQuery(fromjson("{a: {$elemMatch: {b: /foo/}}, z: 1}"));
+
+ assertNumSolutions(2U);
+ assertSolutionExists("{cscan: {dir: 1}}");
+ assertSolutionExists("{fetch: {filter: {a:{$elemMatch:{b:/foo/}}, z:1}, node: "
+ "{ixscan: {filter: null, pattern: {'a.b': 1}}}}}");
+ }
+
+ // SERVER-14180
+ TEST_F(QueryPlannerTest, ElemMatchEmbeddedRegexAnd2) {
+ addIndex(BSON("a.b" << 1));
+ runQuery(fromjson("{a: {$elemMatch: {b: /foo/, b: 3}}, z: 1}"));
+
+ assertNumSolutions(2U);
+ assertSolutionExists("{cscan: {dir: 1}}");
+ assertSolutionExists("{fetch: {filter: {a:{$elemMatch:{b:/foo/,b:3}}, z:1}, node: "
+ "{ixscan: {filter: null, pattern: {'a.b': 1}}}}}");
+ }
+
// $not can appear as a value operator inside of an elemMatch (value). We shouldn't crash if we
// see it.
TEST_F(QueryPlannerTest, ElemMatchWithNotInside) {