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 09:38:53 -0400 |
commit | 2453cec627bb8f6100980dea273ac9eb54ecd645 (patch) | |
tree | 8270e6d297add97c7f72338220b88871227020af /src/mongo/db/query | |
parent | ffaa85ae89335efbef26338a12cc41b351fc8bda (diff) | |
download | mongo-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.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 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) { |