summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjoshua <80741223+jlap199@users.noreply.github.com>2022-09-23 22:45:01 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-09-23 23:18:32 +0000
commit05cda545eb5d1911753cbd3c8004aac9308d890c (patch)
treebe8a8479ec486e97e32172946c50801e71e5c7cf /src
parent6552887793ccf7dc0c52ff7e19167f10990b6567 (diff)
downloadmongo-05cda545eb5d1911753cbd3c8004aac9308d890c.tar.gz
SERVER-68115 Do not drop empty path component from elemMatch path during index selection
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/query/planner_ixselect.cpp20
1 files changed, 6 insertions, 14 deletions
diff --git a/src/mongo/db/query/planner_ixselect.cpp b/src/mongo/db/query/planner_ixselect.cpp
index 9e52daeb6ea..bb7c7cec186 100644
--- a/src/mongo/db/query/planner_ixselect.cpp
+++ b/src/mongo/db/query/planner_ixselect.cpp
@@ -257,15 +257,11 @@ void QueryPlannerIXSelect::getFields(const MatchExpression* node,
// Leaf nodes with a path and some array operators.
if (Indexability::nodeCanUseIndexOnOwnField(node)) {
out->insert(prefix + node->path().toString());
- } else if (Indexability::arrayUsesIndexOnChildren(node)) {
+ } else if (Indexability::arrayUsesIndexOnChildren(node) && !node->path().empty()) {
// If the array uses an index on its children, it's something like
// {foo : {$elemMatch: {bar: 1}}}, in which case the predicate is really over foo.bar.
- //
- // When we have {foo: {$all: [{$elemMatch: {a: 1}}], the path of the embedded elemMatch
- // is empty. We don't want to append a dot in that case as the field would be foo..a.
- if (!node->path().empty()) {
- prefix += node->path().toString() + ".";
- }
+ // Note we skip empty path components since they are not allowed in index key patterns.
+ prefix += node->path().toString() + ".";
for (size_t i = 0; i < node->numChildren(); ++i) {
getFields(node->getChild(i), prefix, out);
@@ -783,7 +779,8 @@ void QueryPlannerIXSelect::_rateIndices(MatchExpression* node,
childRt->path = rt->path;
node->getChild(0)->setTag(childRt);
}
- } else if (Indexability::arrayUsesIndexOnChildren(node)) {
+ } else if (Indexability::arrayUsesIndexOnChildren(node) && !node->path().empty()) {
+ // Note we skip empty path components since they are not allowed in index key patterns.
const auto newPath = prefix + node->path().toString();
ElemMatchContext newContext;
// Note this StringData is unowned and references the string declared on the stack here.
@@ -794,12 +791,7 @@ void QueryPlannerIXSelect::_rateIndices(MatchExpression* node,
// If the array uses an index on its children, it's something like
// {foo: {$elemMatch: {bar: 1}}}, in which case the predicate is really over foo.bar.
- //
- // When we have {foo: {$all: [{$elemMatch: {a: 1}}], the path of the embedded elemMatch
- // is empty. We don't want to append a dot in that case as the field would be foo..a.
- if (!node->path().empty()) {
- prefix += node->path().toString() + ".";
- }
+ prefix += node->path().toString() + ".";
for (size_t i = 0; i < node->numChildren(); ++i) {
_rateIndices(node->getChild(i), prefix, indices, collator, newContext);
}