summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Storch <david.storch@10gen.com>2014-05-09 13:55:49 -0400
committerDavid Storch <david.storch@10gen.com>2014-05-09 17:15:14 -0400
commitd19801d6209d6635e4fb9c42245723f1f1869bf0 (patch)
tree67e4af674867864a2aa8f95581b50ec02529fe44 /src
parent4fd34d5272e6b282f5b98b7b65c4ba2c092d93fb (diff)
downloadmongo-d19801d6209d6635e4fb9c42245723f1f1869bf0.tar.gz
SERVER-13890 index bounds builder should not pass already-constructed intervals to translate()
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/query/index_bounds_builder.cpp12
-rw-r--r--src/mongo/db/query/index_bounds_builder_test.cpp15
-rw-r--r--src/mongo/db/query/query_planner_test.cpp12
3 files changed, 38 insertions, 1 deletions
diff --git a/src/mongo/db/query/index_bounds_builder.cpp b/src/mongo/db/query/index_bounds_builder.cpp
index 7bdb615b678..591cc11513b 100644
--- a/src/mongo/db/query/index_bounds_builder.cpp
+++ b/src/mongo/db/query/index_bounds_builder.cpp
@@ -197,7 +197,14 @@ namespace mongo {
const IndexEntry& index,
OrderedIntervalList* oilOut,
BoundsTightness* tightnessOut) {
- translate(expr, elt, index, oilOut, tightnessOut);
+ OrderedIntervalList arg;
+ translate(expr, elt, index, &arg, tightnessOut);
+
+ // Append the new intervals to oilOut.
+ oilOut->intervals.insert(oilOut->intervals.end(), arg.intervals.begin(),
+ arg.intervals.end());
+
+ // Union the appended intervals with the existing ones.
unionize(oilOut);
}
@@ -216,6 +223,9 @@ namespace mongo {
const IndexEntry& index,
OrderedIntervalList* oilOut,
BoundsTightness* tightnessOut) {
+ // We expect that the OIL we are constructing starts out empty.
+ invariant(oilOut->intervals.empty());
+
oilOut->name = elt.fieldName();
bool isHashed = false;
diff --git a/src/mongo/db/query/index_bounds_builder_test.cpp b/src/mongo/db/query/index_bounds_builder_test.cpp
index 1420e48b69c..0a89cef23fb 100644
--- a/src/mongo/db/query/index_bounds_builder_test.cpp
+++ b/src/mongo/db/query/index_bounds_builder_test.cpp
@@ -1104,4 +1104,19 @@ namespace {
ASSERT_EQUALS(tightness, IndexBoundsBuilder::EXACT);
}
+ TEST(IndexBoundsBuilderTest, UnionizeWithNE) {
+ IndexEntry testIndex = IndexEntry(BSONObj());
+ vector<BSONObj> toUnionize;
+ toUnionize.push_back(fromjson("{a: {$ne: 3}}"));
+ toUnionize.push_back(fromjson("{a: {$ne: 4}}}"));
+ OrderedIntervalList oil;
+ IndexBoundsBuilder::BoundsTightness tightness;
+ testTranslateAndUnion(toUnionize, &oil, &tightness);
+ ASSERT_EQUALS(oil.name, "a");
+ ASSERT_EQUALS(oil.intervals.size(), 1U);
+ ASSERT_EQUALS(Interval::INTERVAL_EQUALS, oil.intervals[0].compare(
+ IndexBoundsBuilder::allValues()));
+ ASSERT_EQUALS(tightness, IndexBoundsBuilder::EXACT);
+ }
+
} // namespace
diff --git a/src/mongo/db/query/query_planner_test.cpp b/src/mongo/db/query/query_planner_test.cpp
index fb54f5052dd..19e1fe7ad13 100644
--- a/src/mongo/db/query/query_planner_test.cpp
+++ b/src/mongo/db/query/query_planner_test.cpp
@@ -3118,6 +3118,18 @@ namespace {
"c: [[1,10,false,false]]}}}}}");
}
+ // Test that planner properly unionizes the index bounds for two negation
+ // predicates (SERVER-13890).
+ TEST_F(QueryPlannerTest, IndexBoundsOrOfNegations) {
+ addIndex(BSON("a" << 1));
+ runQuery(fromjson("{$or: [{a: {$ne: 3}}, {a: {$ne: 4}}]}"));
+
+ assertNumSolutions(2U);
+ assertSolutionExists("{cscan: {dir: 1}}");
+ assertSolutionExists("{fetch: {filter: null, node: {ixscan: {pattern: {a:1}, "
+ "bounds: {a: [['MinKey','MaxKey',true,true]]}}}}}");
+ }
+
//
// Tests related to building index bounds for multikey
// indices, combined with compound and $elemMatch