diff options
author | David Storch <david.storch@10gen.com> | 2018-01-12 18:19:53 -0500 |
---|---|---|
committer | David Storch <david.storch@10gen.com> | 2018-01-19 13:03:16 -0500 |
commit | 92d58a1815b917d165c39235f9fe5b8a319072c3 (patch) | |
tree | e803223fe16ae93c25ab2ed968d047dd967b37b5 /src/mongo/db/matcher | |
parent | c2601667cb409d762e9f0baa9c175f274a51e72c (diff) | |
download | mongo-92d58a1815b917d165c39235f9fe5b8a319072c3.tar.gz |
SERVER-32690 Fix invariant failure in agg renamed paths optimization.
Diffstat (limited to 'src/mongo/db/matcher')
-rw-r--r-- | src/mongo/db/matcher/expression_algo_test.cpp | 19 | ||||
-rw-r--r-- | src/mongo/db/matcher/expression_path.h | 11 |
2 files changed, 26 insertions, 4 deletions
diff --git a/src/mongo/db/matcher/expression_algo_test.cpp b/src/mongo/db/matcher/expression_algo_test.cpp index ca0825b3185..4b0bacb1b9f 100644 --- a/src/mongo/db/matcher/expression_algo_test.cpp +++ b/src/mongo/db/matcher/expression_algo_test.cpp @@ -1186,6 +1186,25 @@ TEST(SplitMatchExpression, ShouldMoveMaxLengthAcrossRename) { ASSERT_FALSE(splitExpr.second.get()); } +TEST(SplitMatchExpression, ShouldMoveIndependentPredicateWhenThereAreMultipleRenames) { + // Designed to reproduce SERVER-32690. + BSONObj matchPredicate = fromjson("{y: 3}"); + boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); + auto matcher = MatchExpressionParser::parse(matchPredicate, std::move(expCtx)); + ASSERT_OK(matcher.getStatus()); + + StringMap<std::string> renames{{"y", "x"}, {"x", "x"}}; + std::pair<unique_ptr<MatchExpression>, unique_ptr<MatchExpression>> splitExpr = + expression::splitMatchExpressionBy(std::move(matcher.getValue()), {}, renames); + + ASSERT_TRUE(splitExpr.first.get()); + BSONObjBuilder firstBob; + splitExpr.first->serialize(&firstBob); + ASSERT_BSONOBJ_EQ(firstBob.obj(), fromjson("{x: {$eq: 3}}")); + + ASSERT_FALSE(splitExpr.second.get()); +} + TEST(MapOverMatchExpression, DoesMapOverLogicalNodes) { BSONObj matchPredicate = fromjson("{a: {$not: {$eq: 1}}}"); boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest()); diff --git a/src/mongo/db/matcher/expression_path.h b/src/mongo/db/matcher/expression_path.h index 189d9cb4a3b..89cf953fd35 100644 --- a/src/mongo/db/matcher/expression_path.h +++ b/src/mongo/db/matcher/expression_path.h @@ -86,11 +86,10 @@ public: void applyRename(const StringMap<std::string>& renameList) { FieldRef pathFieldRef(_path); - int renamesFound = 0; + size_t renamesFound = 0u; for (auto rename : renameList) { if (rename.first == _path) { _rewrittenPath = rename.second; - setPath(_rewrittenPath); ++renamesFound; } @@ -104,14 +103,18 @@ public: // Replace the chopped off components with the component names resulting from the // rename. _rewrittenPath = str::stream() << rename.second << "." << pathTail.toString(); - setPath(_rewrittenPath); ++renamesFound; } } // There should never be multiple applicable renames. - invariant(renamesFound <= 1); + invariant(renamesFound <= 1u); + if (renamesFound == 1u) { + // There is an applicable rename. Modify the path of this expression to use the new + // name. + setPath(_rewrittenPath); + } } protected: |