diff options
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/query/planner_analysis.cpp | 35 | ||||
-rw-r--r-- | src/mongo/db/query/query_solution.cpp | 48 |
2 files changed, 47 insertions, 36 deletions
diff --git a/src/mongo/db/query/planner_analysis.cpp b/src/mongo/db/query/planner_analysis.cpp index d98deab746b..c8b04888b30 100644 --- a/src/mongo/db/query/planner_analysis.cpp +++ b/src/mongo/db/query/planner_analysis.cpp @@ -324,26 +324,25 @@ bool explodeNode(const QuerySolutionNode* node, for (size_t pidx = 0; pidx < prefixIndices.size(); pidx++) { invariant(pidx < isn->iets.size()); const auto& iet = isn->iets[pidx]; - if (const auto* ietEval = iet.cast<interval_evaluation_tree::EvalNode>(); ietEval) { - if (ietEval->matchType() == MatchExpression::MATCH_IN) { - auto ietExplode = interval_evaluation_tree::IET::make< - interval_evaluation_tree::ExplodeNode>( - iet, std::make_pair(nodeIndex, pidx), prefixIndices[pidx]); - child->iets.push_back(std::move(ietExplode)); - } else { - child->iets.push_back(iet); + auto needsExplodeNode = [&]() { + if (const auto* ietEval = iet.cast<interval_evaluation_tree::EvalNode>(); + ietEval) { + return ietEval->matchType() == MatchExpression::MATCH_IN; + } else if (const auto* ietConst = + iet.cast<interval_evaluation_tree::ConstNode>(); + ietConst) { + return ietConst->oil.intervals.size() > 1; } - } else if (const auto* ietConst = iet.cast<interval_evaluation_tree::ConstNode>(); - ietConst) { - OrderedIntervalList oilChild(ietConst->oil.name); - oilChild.intervals.push_back(ietConst->oil.intervals[prefixIndices[pidx]]); - invariant(oilChild.isPoint()); - auto ietConstChild = - interval_evaluation_tree::IET::make<interval_evaluation_tree::ConstNode>( - oilChild); - child->iets.push_back(ietConstChild); - } else { MONGO_UNREACHABLE; + }(); + + if (needsExplodeNode) { + auto ietExplode = + interval_evaluation_tree::IET::make<interval_evaluation_tree::ExplodeNode>( + iet, std::make_pair(nodeIndex, pidx), prefixIndices[pidx]); + child->iets.push_back(std::move(ietExplode)); + } else { + child->iets.push_back(std::move(iet)); } } // Copy the rest of the unexploded IETs directly into the new child. diff --git a/src/mongo/db/query/query_solution.cpp b/src/mongo/db/query/query_solution.cpp index 80dc94b6b64..4f7c9b161e5 100644 --- a/src/mongo/db/query/query_solution.cpp +++ b/src/mongo/db/query/query_solution.cpp @@ -899,27 +899,39 @@ std::set<std::string> extractEqualityFields( // If we have an IET for this field in our index bounds, we determine whether it // guarantees that, upon evaluation, we will have point bounds for the corresponding - // field in our index. In particular, if the IET evaluates to a ConstNode or an equality - // EvalNode, then this field represents an equality. + // field in our index. In particular, if the IET evaluates to a ConstNode, an equality + // EvalNode, or an ExplodeNode, then this field represents an equality. if (iets && !iets->empty()) { const auto& iet = (*iets)[i]; - const auto* constNodePtr = iet.cast<interval_evaluation_tree::ConstNode>(); - const auto* evalNodePtr = iet.cast<interval_evaluation_tree::EvalNode>(); - const auto isEquality = - evalNodePtr && evalNodePtr->matchType() == MatchExpression::MatchType::EQ; - if (!constNodePtr && !isEquality) - continue; + auto mustBePointInterval = [&]() { + if (const auto* constNode = iet.cast<interval_evaluation_tree::ConstNode>(); + constNode) { + // If we have 'constNodePtr', it must be the case that the interval that it + // contains is the same as 'ival'. + tassert(7426201, + "'constNode' must have a single interval", + constNode->oil.intervals.size() == 1); + tassert( + 7426202, + "'constNode' must have the same point interval as the one in 'bounds'", + constNode->oil.intervals[0].equals(ival)); + return true; + } else if (const auto* evalNode = + iet.cast<interval_evaluation_tree::EvalNode>(); + evalNode) { + if (evalNode->matchType() == MatchExpression::MatchType::EQ) { + return true; + } + } else if (const auto* explodeNode = + iet.cast<interval_evaluation_tree::ExplodeNode>(); + explodeNode) { + return true; + } + return false; + }(); - // If we have 'constNodePtr', it must be the case that the interval that it contains - // is the same as 'ival'. - if (constNodePtr) { - tassert(7426201, - "'constNodePtr' must have a single interval", - constNodePtr->oil.intervals.size() == 1); - tassert( - 7426202, - "'constNodePtr' must have the same point interval as the one in 'bounds'", - constNodePtr->oil.intervals[0].equals(ival)); + if (!mustBePointInterval) { + continue; } } equalityFields.insert(oil.name); |