diff options
| author | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-11 15:07:35 -0300 |
|---|---|---|
| committer | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-11 15:07:35 -0300 |
| commit | 4cb8841196d0625dfa3825aa326f071cd27c7b8b (patch) | |
| tree | 1682a647d4463397c119183369ae6f750d5fdcff /src/mongo/db/query/plan_enumerator.cpp | |
| parent | aa03c6362cbaa767638e6eed9b031d86dd2643d1 (diff) | |
| parent | 8f0827553e09872941945a093b647a4211a9db7f (diff) | |
Update upstream source from tag 'upstream/6.0.0'master
Update to upstream version '6.0.0'
with Debian dir 5604a80ec1c96ca76f25f40d78e6ef855abec322
Diffstat (limited to 'src/mongo/db/query/plan_enumerator.cpp')
| -rw-r--r-- | src/mongo/db/query/plan_enumerator.cpp | 52 |
1 files changed, 17 insertions, 35 deletions
diff --git a/src/mongo/db/query/plan_enumerator.cpp b/src/mongo/db/query/plan_enumerator.cpp index 9e30afa0049..a11bc9b415a 100644 --- a/src/mongo/db/query/plan_enumerator.cpp +++ b/src/mongo/db/query/plan_enumerator.cpp @@ -35,7 +35,6 @@ #include "mongo/db/query/index_tag.h" #include "mongo/db/query/indexability.h" -#include "mongo/db/query/query_planner_common.h" #include "mongo/logv2/log.h" #include "mongo/util/string_map.h" @@ -59,8 +58,8 @@ std::string getPathPrefix(std::string path) { * is a predicate that is required to use an index. */ bool expressionRequiresIndex(const MatchExpression* node) { - return QueryPlannerCommon::countNodes(node, MatchExpression::GEO_NEAR) > 0 || - QueryPlannerCommon::countNodes(node, MatchExpression::TEXT) > 0; + return CanonicalQuery::countNodes(node, MatchExpression::GEO_NEAR) > 0 || + CanonicalQuery::countNodes(node, MatchExpression::TEXT) > 0; } size_t getPathLength(const MatchExpression* expr) { @@ -338,8 +337,6 @@ string PlanEnumerator::NodeAssignment::toString() const { str::stream ss; ss << "ALL OF (lockstep): {"; ss << "\n\ttotalEnumerated: " << lockstepOrAssignment->totalEnumerated; - ss << "\n\texhaustedLockstepIteration: " - << lockstepOrAssignment->exhaustedLockstepIteration; ss << "\n\tsubnodes: [ "; for (auto&& node : lockstepOrAssignment->subnodes) { ss << "\n\t\t{"; @@ -1290,8 +1287,6 @@ void PlanEnumerator::getIndexedPreds(MatchExpression* node, std::vector<MatchExpression*>* indexedPreds) { if (Indexability::nodeCanUseIndexOnOwnField(node)) { RelevantTag* rt = static_cast<RelevantTag*>(node->getTag()); - tassert(9074700, "RelevantTag is not assigned to the match expression node", rt != nullptr); - if (context.elemMatchExpr) { // If we're in an $elemMatch context, store the // innermost parent $elemMatch, as well as the @@ -1308,7 +1303,7 @@ void PlanEnumerator::getIndexedPreds(MatchExpression* node, indexedPreds->push_back(node); } else if (Indexability::isBoundsGeneratingNot(node)) { getIndexedPreds(node->getChild(0), context, indexedPreds); - } else if (Indexability::isBoundsGeneratingElemMatchObject(node)) { + } else if (MatchExpression::ELEM_MATCH_OBJECT == node->matchType()) { PrepMemoContext childContext; childContext.elemMatchExpr = node; for (size_t i = 0; i < node->numChildren(); ++i) { @@ -1694,8 +1689,8 @@ bool PlanEnumerator::LockstepOrAssignment::allIdentical() const { return true; } -bool PlanEnumerator::LockstepOrAssignment::shouldResetBeforeProceeding(size_t totalEnumerated, - size_t orLimit) const { +bool PlanEnumerator::LockstepOrAssignment::shouldResetBeforeProceeding( + size_t totalEnumerated) const { if (totalEnumerated == 0 || !exhaustedLockstepIteration) { return false; } @@ -1705,12 +1700,7 @@ bool PlanEnumerator::LockstepOrAssignment::shouldResetBeforeProceeding(size_t to if (!subnode.maxIterCount) { return false; // Haven't yet looped over this child entirely, not ready yet. } - totalPossibleEnumerations *= subnode.maxIterCount.value(); - // If 'totalPossibleEnumerations' reaches the limit, we can just shortcut it. Otherwise, - // 'totalPossibleEnumerations' could overflow if we have a large $or. - if (totalPossibleEnumerations >= orLimit) { - return false; - } + totalPossibleEnumerations *= subnode.maxIterCount.get(); } // If we're able to compute a total number expected enumerations, we must have already cycled @@ -1747,7 +1737,7 @@ bool PlanEnumerator::_nextMemoForLockstepOrAssignment( } // Edge case: if every child has only one option available, we are already finished // enumerating. - if (assignment->shouldResetBeforeProceeding(assignment->totalEnumerated, _orLimit)) { + if (assignment->shouldResetBeforeProceeding(assignment->totalEnumerated)) { assignment->exhaustedLockstepIteration = false; return true; // We're back at the beginning, no need to reset. } @@ -1774,35 +1764,27 @@ bool PlanEnumerator::_nextMemoForLockstepOrAssignment( } }; advanceOnce(); - if (assignment->allIdentical()) { - // All sub-nodes have the same enumeration state, skip this one since we already did it - // above. This is expected to happen pretty often. For example, if we have two subnodes each - // enumerating two states, we'd expect the order to be: 00, 11 (these two iterated above), - // then 00 (skipped here when we fall through after finishing lockstep iteration), then 10, - // 01, then finally 11 (skipped here). - // - // In this example, when we finally roll back to 00, enumeration is complete. We will fall - // through the code below which is responsible for resetting all enumeration state to the - // starting point (which need not reset the child nodes in this case because they already - // all rolled back to the starting point of 00). Finally, we return true to indicate that - // all possibilities have been enumerated. + while (assignment->allIdentical()) { + // All sub-nodes have the same enumeration state, skip this one since we already did + // it above. This is expected to happen pretty often. For example, if we have two subnodes + // each enumerating two states, we'd expect the order to be: 00, 11 (these two iterated + // above), then 00 (skipped by falling through above after finishing lockstep iteration), + // then 10, 11 (skipped here), 00 (skipped here), then finally 01. advanceOnce(); } // This special ordering is tricky to reset. Because it iterates the sub nodes in such a // unique order, it can be difficult to know when it has actually finished iterating. Our // strategy is just to compute a total and go back to the beginning once we hit that total. - if (!assignment->shouldResetBeforeProceeding(assignment->totalEnumerated, _orLimit)) { + if (!assignment->shouldResetBeforeProceeding(assignment->totalEnumerated)) { return false; } // Reset! for (auto&& subnode : assignment->subnodes) { - if (subnode.iterationCount != 0) { - while (!nextMemo(subnode.memoId)) { - // Keep advancing till it rolls over. - } - subnode.iterationCount = 0; + while (!nextMemo(subnode.memoId)) { + // Keep advancing till it rolls over. } + subnode.iterationCount = 0; } assignment->exhaustedLockstepIteration = false; return true; |
