0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

SERVER-18309 have {$in: [.., null, ..]} not use sparse indexes

Closes #979

Signed-off-by: Jason Rassi <rassi@10gen.com>
This commit is contained in:
Qingyang Chen 2015-06-05 16:10:06 -04:00 committed by Jason Rassi
parent 2bf8ac5739
commit 2b44747156
4 changed files with 34 additions and 4 deletions

View File

@ -45,12 +45,19 @@ namespace mongo {
for (BSONElement elem : keyPattern) {
_pathDiscriminatorsMap[elem.fieldNameStringData()].push_back(
[] (const MatchExpression* queryExpr) {
if (queryExpr->matchType() != MatchExpression::EQ) {
if (queryExpr->matchType() == MatchExpression::EQ) {
const auto* queryExprEquality =
static_cast<const EqualityMatchExpression*>(queryExpr);
return !queryExprEquality->getData().isNull();
}
else if (queryExpr->matchType() == MatchExpression::MATCH_IN) {
const auto* queryExprIn =
static_cast<const InMatchExpression*>(queryExpr);
return !queryExprIn->getData().hasNull();
}
else {
return true;
}
const auto* queryExprEquality =
static_cast<const EqualityMatchExpression*>(queryExpr);
return !queryExprEquality->getData().isNull();
}
);
}

View File

@ -60,6 +60,11 @@ namespace {
const IndexabilityDiscriminator& disc = discriminators[0];
ASSERT_EQ(true, disc(parseMatchExpression(BSON("a" << 1)).get()));
ASSERT_EQ(false, disc(parseMatchExpression(BSON("a" << BSONNULL)).get()));
ASSERT_EQ(true,
disc(parseMatchExpression(BSON("a" << BSON("$in" << BSON_ARRAY(1)))).get()));
ASSERT_EQ(false,
disc(parseMatchExpression(BSON("a" <<
BSON("$in" << BSON_ARRAY(BSONNULL)))).get()));
}
// Test sparse index discriminators for a compound sparse index.

View File

@ -154,6 +154,14 @@ namespace mongo {
}
}
// Can't check for $in w/ null element w/a sparse index.
if (exprtype == MatchExpression::MATCH_IN && index.sparse) {
const InMatchExpression* expr = static_cast<const InMatchExpression*>(node);
if (expr->getData().hasNull()) {
return false;
}
}
// We can't use a btree-indexed field for geo expressions.
if (exprtype == MatchExpression::GEO || exprtype == MatchExpression::GEO_NEAR) {
return false;

View File

@ -1307,6 +1307,16 @@ namespace {
"node: {ixscan: {pattern: {a: 1}}}}}");
}
TEST_F(QueryPlannerTest, InSparseIndex) {
addIndex(fromjson("{a: 1}"),
false, // multikey
true); // sparse
runQuery(fromjson("{a: {$in: [null]}}"));
assertNumSolutions(1U);
assertSolutionExists("{cscan: {dir: 1, filter: {a: {$in: [null]}}}}");
}
TEST_F(QueryPlannerTest, InCompoundIndexFirst) {
addIndex(fromjson("{a: 1, b: 1}"));
runQuery(fromjson("{a: {$in: [1, 2]}, b: 3}"));