diff options
author | David Storch <david.storch@10gen.com> | 2015-05-29 19:15:19 -0400 |
---|---|---|
committer | David Storch <david.storch@10gen.com> | 2015-07-10 17:11:16 -0400 |
commit | 15c72c8570c63e2e6ba0a3d339a8286d0be604db (patch) | |
tree | 96cc37b3259e9ce7472132b8c414eb614317c037 /src/mongo/db/query/canonical_query_test.cpp | |
parent | 9c63b79a8d5c8d19663850f9d668a3581dea77d5 (diff) | |
download | mongo-15c72c8570c63e2e6ba0a3d339a8286d0be604db.tar.gz |
SERVER-13732 rewrite contained $or queries to rooted $or in the SubplanStage
This allows queries with an $or contained within an explicit or implicit $and to be answered with
more efficient plans. It also expands the use of the SubplanStage to include contained $or queries
and therefore may reduce the number of plans considered for these queries.
Diffstat (limited to 'src/mongo/db/query/canonical_query_test.cpp')
-rw-r--r-- | src/mongo/db/query/canonical_query_test.cpp | 50 |
1 files changed, 21 insertions, 29 deletions
diff --git a/src/mongo/db/query/canonical_query_test.cpp b/src/mongo/db/query/canonical_query_test.cpp index 35f3976afdf..7d90620e818 100644 --- a/src/mongo/db/query/canonical_query_test.cpp +++ b/src/mongo/db/query/canonical_query_test.cpp @@ -29,6 +29,7 @@ #include "mongo/db/query/canonical_query.h" #include "mongo/db/json.h" +#include "mongo/db/namespace_string.h" #include "mongo/unittest/unittest.h" namespace mongo { @@ -454,10 +455,6 @@ TEST(CanonicalQueryTest, SortTreeNumChildrenComparison) { "{$or: [{a: 1, b: 1}, {a: 1, b: 1, c: 1}]}"); } -// -// Tests for CanonicalQuery::logicalRewrite -// - /** * Utility function to create a CanonicalQuery */ @@ -479,31 +476,6 @@ std::unique_ptr<CanonicalQuery> canonicalize(const char* queryStr, return std::move(statusWithCQ.getValue()); } -// Don't do anything with a double OR. -TEST(CanonicalQueryTest, RewriteNoDoubleOr) { - string queryStr = "{$or:[{a:1}, {b:1}], $or:[{c:1}, {d:1}], e:1}"; - BSONObj queryObj = fromjson(queryStr); - unique_ptr<MatchExpression> base(parseMatchExpression(queryObj)); - unique_ptr<MatchExpression> rewrite( - CanonicalQuery::logicalRewrite(base->shallowClone().release())); - assertEquivalent(queryStr.c_str(), base.get(), rewrite.get()); -} - -// Do something with a single or. -TEST(CanonicalQueryTest, RewriteSingleOr) { - // Rewrite of this... - string queryStr = "{$or:[{a:1}, {b:1}], e:1}"; - BSONObj queryObj = fromjson(queryStr); - unique_ptr<MatchExpression> rewrite( - CanonicalQuery::logicalRewrite(parseMatchExpression(queryObj))); - - // Should look like this. - string rewriteStr = "{$or:[{a:1, e:1}, {b:1, e:1}]}"; - BSONObj rewriteObj = fromjson(rewriteStr); - unique_ptr<MatchExpression> base(parseMatchExpression(rewriteObj)); - assertEquivalent(queryStr.c_str(), base.get(), rewrite.get()); -} - /** * Test function for CanonicalQuery::normalize. */ @@ -537,5 +509,25 @@ TEST(CanonicalQueryTest, NormalizeQueryTree) { "{$and: [{a: 1}, {b: 1}, {c: 1}]}"); } +TEST(CanonicalQueryTest, CanonicalizeFromBaseQuery) { + const bool isExplain = true; + const std::string cmdStr = + "{find:'bogusns', filter:{$or:[{a:1,b:1},{a:1,c:1}]}, projection:{a:1}, sort:{b:1}}"; + auto lpq = assertGet(LiteParsedQuery::makeFromFindCommand(nss, fromjson(cmdStr), isExplain)); + auto baseCq = assertGet(CanonicalQuery::canonicalize(lpq.release())); + + MatchExpression* firstClauseExpr = baseCq->root()->getChild(0); + auto childCq = assertGet(CanonicalQuery::canonicalize(*baseCq, firstClauseExpr)); + + BSONObjBuilder expectedFilterBuilder; + firstClauseExpr->toBSON(&expectedFilterBuilder); + BSONObj expectedFilter = expectedFilterBuilder.obj(); + + ASSERT_EQ(childCq->getParsed().getFilter(), expectedFilter); + ASSERT_EQ(childCq->getParsed().getProj(), baseCq->getParsed().getProj()); + ASSERT_EQ(childCq->getParsed().getSort(), baseCq->getParsed().getSort()); + ASSERT_TRUE(childCq->getParsed().isExplain()); +} + } // namespace } // namespace mongo |