diff options
author | Hana Pearlman <hana.pearlman@mongodb.com> | 2022-01-27 01:33:54 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-01-27 02:00:43 +0000 |
commit | fc9b2eab13efc7b63e69595d54a5663e17913b8a (patch) | |
tree | 8bcf1454cde03dfcabadd1462ac51294898e81e1 /src/mongo/db/exec | |
parent | 7c60c33a172067cd76b72bdb5b72c7381b3899ef (diff) | |
download | mongo-fc9b2eab13efc7b63e69595d54a5663e17913b8a.tar.gz |
SERVER-63000: createPredicatesOnBucketLevelField with $in should be treated like $or
Diffstat (limited to 'src/mongo/db/exec')
-rw-r--r-- | src/mongo/db/exec/bucket_unpacker.cpp | 33 |
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"); |