Skip to content

Commit 2453cec

Browse files
committed
SERVER-14180 fix double free in access planning for $elemMatch
1 parent ffaa85a commit 2453cec

File tree

2 files changed

+22
-20
lines changed

2 files changed

+22
-20
lines changed

src/mongo/db/query/planner_access.cpp

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -737,16 +737,6 @@ namespace mongo {
737737

738738
scanState->tightness = IndexBoundsBuilder::INEXACT_FETCH;
739739
mergeWithLeafNode(emChild, scanState);
740-
741-
if (scanState->tightness == IndexBoundsBuilder::INEXACT_COVERED
742-
&& !indices[scanState->currentIndexNumber].multikey) {
743-
// Add the filter to the current index scan. This is optional because
744-
// the entire filter will get affixed to the parent AND. It is here
745-
// as an optimization---an additional filter during the index scan
746-
// stage will cause fewer documents to bubble up to the parent node
747-
// of the execution tree.
748-
addFilterToSolutionNode(scanState->currentScan.get(), emChild, root->matchType());
749-
}
750740
}
751741
else {
752742
if (NULL != scanState->currentScan.get()) {
@@ -762,16 +752,6 @@ namespace mongo {
762752
scanState->currentScan.reset(makeLeafNode(query, indices[scanState->currentIndexNumber],
763753
scanState->ixtag->pos,
764754
emChild, &scanState->tightness));
765-
766-
if (scanState->tightness == IndexBoundsBuilder::INEXACT_COVERED
767-
&& !indices[scanState->currentIndexNumber].multikey) {
768-
// Add the filter to the current index scan. This is optional because
769-
// the entire filter will get affixed to the parent AND. It is here
770-
// as an optimization---an additional filter during the index scan
771-
// stage will cause fewer documents to bubble up to the parent node
772-
// of the execution tree.
773-
addFilterToSolutionNode(scanState->currentScan.get(), emChild, root->matchType());
774-
}
775755
}
776756
}
777757

src/mongo/db/query/query_planner_test.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,6 +1612,28 @@ namespace {
16121612
"{ixscan: {filter: null, pattern: {'a.b': 1}}}}}");
16131613
}
16141614

1615+
// SERVER-14180
1616+
TEST_F(QueryPlannerTest, ElemMatchEmbeddedRegexAnd) {
1617+
addIndex(BSON("a.b" << 1));
1618+
runQuery(fromjson("{a: {$elemMatch: {b: /foo/}}, z: 1}"));
1619+
1620+
assertNumSolutions(2U);
1621+
assertSolutionExists("{cscan: {dir: 1}}");
1622+
assertSolutionExists("{fetch: {filter: {a:{$elemMatch:{b:/foo/}}, z:1}, node: "
1623+
"{ixscan: {filter: null, pattern: {'a.b': 1}}}}}");
1624+
}
1625+
1626+
// SERVER-14180
1627+
TEST_F(QueryPlannerTest, ElemMatchEmbeddedRegexAnd2) {
1628+
addIndex(BSON("a.b" << 1));
1629+
runQuery(fromjson("{a: {$elemMatch: {b: /foo/, b: 3}}, z: 1}"));
1630+
1631+
assertNumSolutions(2U);
1632+
assertSolutionExists("{cscan: {dir: 1}}");
1633+
assertSolutionExists("{fetch: {filter: {a:{$elemMatch:{b:/foo/,b:3}}, z:1}, node: "
1634+
"{ixscan: {filter: null, pattern: {'a.b': 1}}}}}");
1635+
}
1636+
16151637
// $not can appear as a value operator inside of an elemMatch (value). We shouldn't crash if we
16161638
// see it.
16171639
TEST_F(QueryPlannerTest, ElemMatchWithNotInside) {

0 commit comments

Comments
 (0)