summaryrefslogtreecommitdiff
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 10:57:09 -0400
commite52e4e2deb3732a7414cf64b9525843360f4c26d (patch)
treea80ead1870765757cdc6fbaa56e6027476899dda
parent03c83b974897ce58d7cd6f69e27cae7bc1433e2f (diff)
downloadmongo-e52e4e2deb3732a7414cf64b9525843360f4c26d.tar.gz
SERVER-14180 fix double free in access planning for $elemMatch
(cherry picked from commit 2453cec627bb8f6100980dea273ac9eb54ecd645)
-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 ba8ed3644f7..ef9669cd604 100644
--- a/src/mongo/db/query/planner_access.cpp
+++ b/src/mongo/db/query/planner_access.cpp
@@ -736,16 +736,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()) {
@@ -761,16 +751,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 f514b579dd7..41fa983c56b 100644
--- a/src/mongo/db/query/query_planner_test.cpp
+++ b/src/mongo/db/query/query_planner_test.cpp
@@ -1483,6 +1483,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) {