summaryrefslogtreecommitdiff
path: root/src/mongo/db/exec/bucket_unpacker.cpp
diff options
context:
space:
mode:
authorHana Pearlman <hana.pearlman@mongodb.com>2022-01-27 01:33:54 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-01-27 02:00:43 +0000
commitfc9b2eab13efc7b63e69595d54a5663e17913b8a (patch)
tree8bcf1454cde03dfcabadd1462ac51294898e81e1 /src/mongo/db/exec/bucket_unpacker.cpp
parent7c60c33a172067cd76b72bdb5b72c7381b3899ef (diff)
downloadmongo-fc9b2eab13efc7b63e69595d54a5663e17913b8a.tar.gz
SERVER-63000: createPredicatesOnBucketLevelField with $in should be treated like $or
Diffstat (limited to 'src/mongo/db/exec/bucket_unpacker.cpp')
-rw-r--r--src/mongo/db/exec/bucket_unpacker.cpp33
1 files changed, 25 insertions, 8 deletions
diff --git a/src/mongo/db/exec/bucket_unpacker.cpp b/src/mongo/db/exec/bucket_unpacker.cpp
index 2627b680e3c..50e2063257b 100644
--- a/src/mongo/db/exec/bucket_unpacker.cpp
+++ b/src/mongo/db/exec/bucket_unpacker.cpp
@@ -559,19 +559,36 @@ std::unique_ptr<MatchExpression> BucketSpec::createPredicatesOnBucketLevelField(
policy, matchExpr, "can't handle {$eq: null} predicate (inside $in predicate)");
auto result = std::make_unique<OrMatchExpression>();
+
+ bool alwaysTrue = false;
for (auto&& elem : inExpr->getEqualities()) {
// If inExpr is {$in: [X, Y]} then the elems are '0: X' and '1: Y'.
auto eq = std::make_unique<EqualityMatchExpression>(
inExpr->path(), elem, nullptr /*annotation*/, inExpr->getCollator());
- result->add(createComparisonPredicate(eq.get(),
- bucketSpec,
- bucketMaxSpanSeconds,
- collationMatchesDefault,
- pExpCtx,
- haveComputedMetaField,
- assumeNoMixedSchemaData,
- policy));
+ auto child = createComparisonPredicate(eq.get(),
+ bucketSpec,
+ bucketMaxSpanSeconds,
+ collationMatchesDefault,
+ pExpCtx,
+ haveComputedMetaField,
+ assumeNoMixedSchemaData,
+ policy);
+
+ // As with OR, only add the child if it has been succesfully translated, otherwise the
+ // $in cannot be correctly mapped to bucket level fields and we should return nullptr.
+ if (child) {
+ result->add(std::move(child));
+ } else {
+ alwaysTrue = true;
+ if (policy == IneligiblePredicatePolicy::kIgnore)
+ break;
+ }
}
+ if (alwaysTrue)
+ return nullptr;
+
+ // As above, no special case for an empty IN: returning nullptr would be incorrect because
+ // it means 'always-true', here.
return result;
}
return handleIneligible(policy, matchExpr, "can't handle this predicate");