summaryrefslogtreecommitdiff
path: root/src/mongo/db/matcher
diff options
context:
space:
mode:
authorAnton Korshunov <anton.korshunov@mongodb.com>2021-01-31 00:34:57 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-02-14 15:30:07 +0000
commit0fc5b56b12dbdc248556fdfa9da2f44479eac699 (patch)
treedfac279997b20789e8c376fcf5a74fce75b15d22 /src/mongo/db/matcher
parent4dd10ec20b608ec364db1ba4815bbf45d73e8da4 (diff)
downloadmongo-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.cpp45
-rw-r--r--src/mongo/db/matcher/schema/json_schema_parser.cpp1
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()};