summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Storch <david.storch@10gen.com>2014-04-28 11:43:49 -0400
committerDan Pasette <dan@mongodb.com>2014-05-15 19:55:34 -0400
commit8b326cb33c3fa7c78be9c14cc0d9da8266ed9aa2 (patch)
tree9c6acdcebd68e523d88fde1c7a9756e54ab7746c
parentde14e3eed4040db2f105dada80100b9417c37045 (diff)
downloadmongo-8b326cb33c3fa7c78be9c14cc0d9da8266ed9aa2.tar.gz
SERVER-13752 do not attempt to explode for sort with empty bounds
(cherry picked from commit 1f83b5f5e3ad400fe2de0e7427548cb21a05d751)
-rw-r--r--src/mongo/db/query/planner_analysis.cpp7
-rw-r--r--src/mongo/db/query/query_planner_test.cpp23
2 files changed, 30 insertions, 0 deletions
diff --git a/src/mongo/db/query/planner_analysis.cpp b/src/mongo/db/query/planner_analysis.cpp
index 24441a7a811..888ff143cf2 100644
--- a/src/mongo/db/query/planner_analysis.cpp
+++ b/src/mongo/db/query/planner_analysis.cpp
@@ -63,11 +63,18 @@ namespace mongo {
* Returns true if every interval in 'oil' is a point, false otherwise.
*/
bool isUnionOfPoints(const OrderedIntervalList& oil) {
+ // We can't explode if there are empty bounds. Don't consider the
+ // oil a union of points if there are no intervals.
+ if (0 == oil.intervals.size()) {
+ return false;
+ }
+
for (size_t i = 0; i < oil.intervals.size(); ++i) {
if (!oil.intervals[i].isPoint()) {
return false;
}
}
+
return true;
}
diff --git a/src/mongo/db/query/query_planner_test.cpp b/src/mongo/db/query/query_planner_test.cpp
index 871f0c73c94..4ca7e6c4b86 100644
--- a/src/mongo/db/query/query_planner_test.cpp
+++ b/src/mongo/db/query/query_planner_test.cpp
@@ -2070,6 +2070,29 @@ namespace {
"{ixscan: {pattern: {a:1, b:1, c:-1}}}]}}}}");
}
+ // SERVER-13752: don't try to explode if the ordered interval list for
+ // the leading field of the compound index is empty.
+ TEST_F(QueryPlannerTest, CantExplodeWithEmptyBounds) {
+ addIndex(BSON("a" << 1 << "b" << 1));
+ runQuerySortProj(fromjson("{a: {$in: []}}"), BSON("b" << 1), BSONObj());
+
+ assertNumSolutions(2U);
+ assertSolutionExists("{sort: {pattern: {b:1}, limit: 0, node: {cscan: {dir: 1}}}}");
+ assertSolutionExists("{sort: {pattern: {b:1}, limit: 0, node: "
+ "{fetch: {node: {ixscan: {pattern: {a: 1, b: 1}}}}}}}");
+ }
+
+ // SERVER-13752
+ TEST_F(QueryPlannerTest, CantExplodeWithEmptyBounds2) {
+ addIndex(BSON("a" << 1 << "b" << 1 << "c" << 1));
+ runQuerySortProj(fromjson("{a: {$gt: 3, $lt: 0}}"), BSON("b" << 1), BSONObj());
+
+ assertNumSolutions(2U);
+ assertSolutionExists("{sort: {pattern: {b:1}, limit: 0, node: {cscan: {dir: 1}}}}");
+ assertSolutionExists("{sort: {pattern: {b:1}, limit: 0, node: "
+ "{fetch: {node: {ixscan: {pattern: {a:1,b:1,c:1}}}}}}}");
+ }
+
TEST_F(QueryPlannerTest, InWithSortAndLimitTrailingField) {
addIndex(BSON("a" << 1 << "b" << -1 << "c" << 1));
runQuerySortProjSkipLimit(fromjson("{a: {$in: [1, 2]}, b: {$gte: 0}}"),