From e52e4e2deb3732a7414cf64b9525843360f4c26d Mon Sep 17 00:00:00 2001 From: David Storch Date: Thu, 5 Jun 2014 19:00:41 -0400 Subject: SERVER-14180 fix double free in access planning for $elemMatch (cherry picked from commit 2453cec627bb8f6100980dea273ac9eb54ecd645) --- src/mongo/db/query/planner_access.cpp | 20 -------------------- 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) { -- cgit v1.2.1