diff options
author | Anton Korshunov <anton.korshunov@mongodb.com> | 2021-01-31 00:34:57 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-02-14 15:30:07 +0000 |
commit | 0fc5b56b12dbdc248556fdfa9da2f44479eac699 (patch) | |
tree | dfac279997b20789e8c376fcf5a74fce75b15d22 /src/mongo/db/matcher | |
parent | 4dd10ec20b608ec364db1ba4815bbf45d73e8da4 (diff) | |
download | mongo-0fc5b56b12dbdc248556fdfa9da2f44479eac699.tar.gz |
SERVER-51823 Use classic engine to evaluate queries containing expressions not supported in SBE
Diffstat (limited to 'src/mongo/db/matcher')
-rw-r--r-- | src/mongo/db/matcher/expression_parser.cpp | 45 | ||||
-rw-r--r-- | src/mongo/db/matcher/schema/json_schema_parser.cpp | 1 |
2 files changed, 35 insertions, 11 deletions
diff --git a/src/mongo/db/matcher/expression_parser.cpp b/src/mongo/db/matcher/expression_parser.cpp index 7ef37bc2e02..434955fcf95 100644 --- a/src/mongo/db/matcher/expression_parser.cpp +++ b/src/mongo/db/matcher/expression_parser.cpp @@ -491,7 +491,6 @@ StatusWithMatchExpression parseExpr(StringData name, if ((allowedFeatures & MatchExpressionParser::AllowedFeatures::kExpr) == 0u) { return {Status(ErrorCodes::QueryFeatureNotAllowed, "$expr is not allowed in this context")}; } - return {std::make_unique<ExprMatchExpression>( std::move(elem), expCtx, @@ -620,6 +619,10 @@ StatusWithMatchExpression parseType(StringData name, str::stream() << name << " must match at least one type")}; } + if constexpr (std::is_same_v<T, InternalSchemaTypeExpression> || + std::is_same_v<T, InternalSchemaBinDataEncryptedTypeExpression>) { + expCtx->sbeCompatible = false; + } return {std::make_unique<T>( name, std::move(typeSet.getValue()), @@ -734,7 +737,8 @@ StatusWithMatchExpression parseBitTest(StringData name, return {std::move(bitTestMatchExpression)}; } -StatusWithMatchExpression parseInternalSchemaFmod(StringData name, BSONElement elem) { +StatusWithMatchExpression parseInternalSchemaFmod( + StringData name, BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& expCtx) { StringData path(name); if (elem.type() != BSONType::Array) return {ErrorCodes::BadValue, @@ -763,6 +767,7 @@ StatusWithMatchExpression parseInternalSchemaFmod(StringData name, BSONElement e return {ErrorCodes::BadValue, str::stream() << path << " has too many elements"}; } + expCtx->sbeCompatible = false; return {std::make_unique<InternalSchemaFmodMatchExpression>( name, d.numberDecimal(), r.numberDecimal())}; } @@ -785,6 +790,7 @@ StatusWithMatchExpression parseInternalSchemaRootDocEq( str::stream() << InternalSchemaRootDocEqMatchExpression::kName << " must be an object, found type " << elem.type())}; } + expCtx->sbeCompatible = false; auto rootDocEq = std::make_unique<InternalSchemaRootDocEqMatchExpression>(elem.embeddedObject()); return {std::move(rootDocEq)}; @@ -795,13 +801,14 @@ StatusWithMatchExpression parseInternalSchemaRootDocEq( * of type 'T' that gets initialized with the resulting integer. */ template <class T> -StatusWithMatchExpression parseInternalSchemaSingleIntegerArgument(StringData name, - BSONElement elem) { +StatusWithMatchExpression parseInternalSchemaSingleIntegerArgument( + StringData name, BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& expCtx) { auto parsedInt = elem.parseIntegerElementToNonNegativeLong(); if (!parsedInt.isOK()) { return parsedInt.getStatus(); } + expCtx->sbeCompatible = false; return {std::make_unique<T>(name, parsedInt.getValue())}; } @@ -821,6 +828,7 @@ StatusWithMatchExpression parseTopLevelInternalSchemaSingleIntegerArgument( if (!parsedInt.isOK()) { return parsedInt.getStatus(); } + expCtx->sbeCompatible = false; return {std::make_unique<T>(parsedInt.getValue())}; } @@ -1055,6 +1063,7 @@ StatusWithMatchExpression parseInternalSchemaAllowedProperties( return properties.getStatus(); } + expCtx->sbeCompatible = false; return {std::make_unique<InternalSchemaAllowedPropertiesMatchExpression>( std::move(properties.getValue()), namePlaceholder.getValue(), @@ -1110,6 +1119,7 @@ StatusWithMatchExpression parseInternalSchemaMatchArrayIndex( return expressionWithPlaceholder.getStatus(); } + expCtx->sbeCompatible = false; return {std::make_unique<InternalSchemaMatchArrayIndexMatchExpression>( path, index.getValue(), std::move(expressionWithPlaceholder.getValue()))}; } @@ -1126,6 +1136,7 @@ StatusWithMatchExpression parseGeo(StringData name, return parseStatus; } auto operatorName = section.firstElementFieldName(); + expCtx->sbeCompatible = false; return {std::make_unique<GeoMatchExpression>( name, gq.release(), @@ -1144,6 +1155,7 @@ StatusWithMatchExpression parseGeo(StringData name, if (!status.isOK()) { return status; } + expCtx->sbeCompatible = false; return {std::make_unique<GeoNearMatchExpression>(name, nq.release(), section)}; } } @@ -1179,6 +1191,9 @@ StatusWithMatchExpression parseTreeTopLevel( temp->add(sub.getValue().release()); } + if constexpr (std::is_same_v<T, InternalSchemaXorMatchExpression>) { + expCtx->sbeCompatible = false; + } return {std::move(temp)}; } @@ -1382,6 +1397,7 @@ StatusWithMatchExpression parseInternalSchemaFixedArityArgument( ++position; } + expCtx->sbeCompatible = false; return {std::make_unique<T>(std::move(expressions))}; } @@ -1428,7 +1444,8 @@ StatusWithMatchExpression parseNot(StringData name, theAnd.release(), doc_validation_error::createAnnotation(expCtx, "$not", BSONObj()))}; } -StatusWithMatchExpression parseInternalSchemaBinDataSubType(StringData name, BSONElement e) { +StatusWithMatchExpression parseInternalSchemaBinDataSubType( + StringData name, BSONElement e, const boost::intrusive_ptr<ExpressionContext>& expCtx) { if (!e.isNumber()) { return Status(ErrorCodes::FailedToParse, str::stream() << InternalSchemaBinDataSubTypeExpression::kName @@ -1450,6 +1467,7 @@ StatusWithMatchExpression parseInternalSchemaBinDataSubType(StringData name, BSO << " value must represent BinData subtype: " << valueAsInt.getValue()); } + expCtx->sbeCompatible = false; return {std::make_unique<InternalSchemaBinDataSubTypeExpression>( name, static_cast<BinDataType>(valueAsInt.getValue()))}; } @@ -1759,16 +1777,16 @@ StatusWithMatchExpression parseSubField(const BSONObj& context, } case PathAcceptingKeyword::INTERNAL_SCHEMA_FMOD: - return parseInternalSchemaFmod(name, e); + return parseInternalSchemaFmod(name, e, expCtx); case PathAcceptingKeyword::INTERNAL_SCHEMA_MIN_ITEMS: { return parseInternalSchemaSingleIntegerArgument<InternalSchemaMinItemsMatchExpression>( - name, e); + name, e, expCtx); } case PathAcceptingKeyword::INTERNAL_SCHEMA_MAX_ITEMS: { return parseInternalSchemaSingleIntegerArgument<InternalSchemaMaxItemsMatchExpression>( - name, e); + name, e, expCtx); } case PathAcceptingKeyword::INTERNAL_SCHEMA_OBJECT_MATCH: { @@ -1786,6 +1804,7 @@ StatusWithMatchExpression parseSubField(const BSONObj& context, return parsedSubObjExpr; } + expCtx->sbeCompatible = false; return {std::make_unique<InternalSchemaObjectMatchExpression>( name, std::move(parsedSubObjExpr.getValue()), @@ -1798,17 +1817,18 @@ StatusWithMatchExpression parseSubField(const BSONObj& context, str::stream() << name << " must be a boolean of value true"}; } + expCtx->sbeCompatible = false; return {std::make_unique<InternalSchemaUniqueItemsMatchExpression>(name)}; } case PathAcceptingKeyword::INTERNAL_SCHEMA_MIN_LENGTH: { return parseInternalSchemaSingleIntegerArgument<InternalSchemaMinLengthMatchExpression>( - name, e); + name, e, expCtx); } case PathAcceptingKeyword::INTERNAL_SCHEMA_MAX_LENGTH: { return parseInternalSchemaSingleIntegerArgument<InternalSchemaMaxLengthMatchExpression>( - name, e); + name, e, expCtx); } case PathAcceptingKeyword::INTERNAL_SCHEMA_MATCH_ARRAY_INDEX: { @@ -1876,6 +1896,8 @@ StatusWithMatchExpression parseSubField(const BSONObj& context, if (!exprWithPlaceholder.isOK()) { return exprWithPlaceholder.getStatus(); } + + expCtx->sbeCompatible = false; return {std::make_unique<InternalSchemaAllElemMatchFromIndexMatchExpression>( name, parsedIndex.getValue(), std::move(exprWithPlaceholder.getValue()))}; } @@ -1885,6 +1907,7 @@ StatusWithMatchExpression parseSubField(const BSONObj& context, } case PathAcceptingKeyword::INTERNAL_SCHEMA_EQ: { + expCtx->sbeCompatible = false; return {std::make_unique<InternalSchemaEqMatchExpression>(name, e)}; } @@ -1893,7 +1916,7 @@ StatusWithMatchExpression parseSubField(const BSONObj& context, } case PathAcceptingKeyword::INTERNAL_SCHEMA_BIN_DATA_SUBTYPE: { - return parseInternalSchemaBinDataSubType(name, e); + return parseInternalSchemaBinDataSubType(name, e, expCtx); } } diff --git a/src/mongo/db/matcher/schema/json_schema_parser.cpp b/src/mongo/db/matcher/schema/json_schema_parser.cpp index ec980d71ebc..c972c05c602 100644 --- a/src/mongo/db/matcher/schema/json_schema_parser.cpp +++ b/src/mongo/db/matcher/schema/json_schema_parser.cpp @@ -1885,6 +1885,7 @@ StatusWithMatchExpression JSONSchemaParser::parse( doc_validation_error::createAnnotation(expCtx, "$jsonSchema", oldAnnotation)); } } + expCtx->sbeCompatible = false; return translation; } catch (const DBException& ex) { return {ex.toStatus()}; |