diff options
author | Andrii Dobroshynski <andrii.dobroshynski@mongodb.com> | 2021-06-17 13:54:21 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-06-17 14:18:37 +0000 |
commit | a6bd767d38ca772b626afd7f90301a9701dda85f (patch) | |
tree | 7192c1522eebde5ef0fdab5ab32b45a0159efed7 /src/mongo/db/matcher/expression_parser.cpp | |
parent | aeab436accc7f83e9625be6b4483aa03a732316b (diff) | |
download | mongo-a6bd767d38ca772b626afd7f90301a9701dda85f.tar.gz |
SERVER-57300 Fix logic for detecting numeric path component to avoid executing with SBE
Diffstat (limited to 'src/mongo/db/matcher/expression_parser.cpp')
-rw-r--r-- | src/mongo/db/matcher/expression_parser.cpp | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/src/mongo/db/matcher/expression_parser.cpp b/src/mongo/db/matcher/expression_parser.cpp index 798c5e59934..84802d9b5f8 100644 --- a/src/mongo/db/matcher/expression_parser.cpp +++ b/src/mongo/db/matcher/expression_parser.cpp @@ -94,16 +94,27 @@ bool hasNode(const MatchExpression* root, MatchExpression::MatchType type) { // TODO SERVER-49852: Currently SBE cannot handle match expressions with numeric path // components due to some of the complexity around how arrays are handled. void disableSBEForNumericPathComponent(const boost::intrusive_ptr<ExpressionContext>& expCtx, - const FieldRef* fieldRef) { + const MatchExpression* node) { + auto fieldRef = node->fieldRef(); if (fieldRef && fieldRef->hasNumericPathComponents()) { expCtx->sbeCompatible = false; + return; + } + for (size_t i = 0; i < node->numChildren(); ++i) { + // For some match expressions trees, there could be a path associated with a node deeper in + // the tree. This is true in particular for negations. For example, {a: {$not: {$gt: 0}}} + // will be converted to a NOT => GT tree, but it is the GT node that carries the path, + // rather than the NOT node. + disableSBEForNumericPathComponent(expCtx, node->getChild(i)); + if (!expCtx->sbeCompatible) + return; } } void addExpressionToRoot(const boost::intrusive_ptr<ExpressionContext>& expCtx, AndMatchExpression* root, std::unique_ptr<MatchExpression> newNode) { - disableSBEForNumericPathComponent(expCtx, newNode->fieldRef()); + disableSBEForNumericPathComponent(expCtx, newNode.get()); root->add(std::move(newNode)); } } // namespace @@ -1582,10 +1593,6 @@ StatusWithMatchExpression parseSubField(const BSONObj& context, expCtx, allowedFeatures); - // The NotMatchExpression below does not have a path, so 's' must be checked for a - // numeric path component instead. - disableSBEForNumericPathComponent(expCtx, s.getValue()->fieldRef()); - return {std::make_unique<NotMatchExpression>( s.getValue().release(), doc_validation_error::createAnnotation(expCtx, AnnotationMode::kIgnoreButDescend))}; @@ -1630,9 +1637,6 @@ StatusWithMatchExpression parseSubField(const BSONObj& context, return parseStatus; } - // The NotMatchExpression below does not have a path, so 's' must be checked for a - // numeric path component instead. - disableSBEForNumericPathComponent(expCtx, temp->fieldRef()); return {std::make_unique<NotMatchExpression>( temp.release(), doc_validation_error::createAnnotation(expCtx, AnnotationMode::kIgnoreButDescend))}; |