diff options
author | David Storch <david.storch@10gen.com> | 2014-06-05 19:00:41 -0400 |
---|---|---|
committer | David Storch <david.storch@10gen.com> | 2014-06-06 10:57:09 -0400 |
commit | e52e4e2deb3732a7414cf64b9525843360f4c26d (patch) | |
tree | a80ead1870765757cdc6fbaa56e6027476899dda | |
parent | 03c83b974897ce58d7cd6f69e27cae7bc1433e2f (diff) | |
download | mongo-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.cpp | 20 | ||||
-rw-r--r-- | src/mongo/db/query/query_planner_test.cpp | 22 |
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) { |