Skip to content

Commit eeef3c3

Browse files
dstorchDan Pasette
authored andcommitted
SERVER-13618 explode for sort tries reversing index scan direction
(cherry picked from commit ce52f31)
1 parent a093bfa commit eeef3c3

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

src/mongo/db/query/planner_analysis.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,17 @@ namespace mongo {
300300
// See if it's the order we're looking for.
301301
BSONObj possibleSort = resultingSortBob.obj();
302302
if (!desiredSort.isPrefixOf(possibleSort)) {
303-
return false;
303+
// We can't get the sort order from the index scan. See if we can
304+
// get the sort by reversing the scan.
305+
BSONObj reversePossibleSort = QueryPlannerCommon::reverseSortObj(possibleSort);
306+
if (!desiredSort.isPrefixOf(reversePossibleSort)) {
307+
// Can't get the sort order from the reversed index scan either. Give up.
308+
return false;
309+
}
310+
else {
311+
// We can get the sort order we need if we reverse the scan.
312+
QueryPlannerCommon::reverseScans(isn);
313+
}
304314
}
305315

306316
// Do some bookkeeping to see how many ixscans we'll create total.

src/mongo/db/query/query_planner_test.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1650,6 +1650,37 @@ namespace {
16501650
"{fetch: {node: {ixscan: {pattern: {a: 1, b: 1, c:1, d:1}}}}}}}");
16511651
}
16521652

1653+
// SERVER-13618: test that exploding scans for sort works even
1654+
// if we must reverse the scan direction.
1655+
TEST_F(QueryPlannerTest, ExplodeMustReverseScans) {
1656+
addIndex(BSON("a" << 1 << "b" << 1 << "c" << 1 << "d" << 1));
1657+
runQuerySortProj(fromjson("{a: {$in: [1, 2]}, b: {$in: [3, 4]}}"),
1658+
BSON("c" << -1), BSONObj());
1659+
1660+
assertNumSolutions(2U);
1661+
assertSolutionExists("{sort: {pattern: {c: -1}, limit: 0, node: {cscan: {dir: 1}}}}");
1662+
assertSolutionExists("{fetch: {node: {mergeSort: {nodes: "
1663+
"[{ixscan: {pattern: {a:1, b:1, c:1, d:1}}},"
1664+
"{ixscan: {pattern: {a:1, b:1, c:1, d:1}}},"
1665+
"{ixscan: {pattern: {a:1, b:1, c:1, d:1}}},"
1666+
"{ixscan: {pattern: {a:1, b:1, c:1, d:1}}}]}}}}");
1667+
}
1668+
1669+
// SERVER-13618
1670+
TEST_F(QueryPlannerTest, ExplodeMustReverseScans2) {
1671+
addIndex(BSON("a" << 1 << "b" << 1 << "c" << -1));
1672+
runQuerySortProj(fromjson("{a: {$in: [1, 2]}, b: {$in: [3, 4]}}"),
1673+
BSON("c" << 1), BSONObj());
1674+
1675+
assertNumSolutions(2U);
1676+
assertSolutionExists("{sort: {pattern: {c: 1}, limit: 0, node: {cscan: {dir: 1}}}}");
1677+
assertSolutionExists("{fetch: {node: {mergeSort: {nodes: "
1678+
"[{ixscan: {pattern: {a:1, b:1, c:-1}}},"
1679+
"{ixscan: {pattern: {a:1, b:1, c:-1}}},"
1680+
"{ixscan: {pattern: {a:1, b:1, c:-1}}},"
1681+
"{ixscan: {pattern: {a:1, b:1, c:-1}}}]}}}}");
1682+
}
1683+
16531684
TEST_F(QueryPlannerTest, InWithSortAndLimitTrailingField) {
16541685
addIndex(BSON("a" << 1 << "b" << -1 << "c" << 1));
16551686
runQuerySortProjSkipLimit(fromjson("{a: {$in: [1, 2]}, b: {$gte: 0}}"),

0 commit comments

Comments
 (0)