diff options
author | Justin Seyster <justin.seyster@mongodb.com> | 2017-08-31 15:44:35 -0400 |
---|---|---|
committer | Justin Seyster <justin.seyster@mongodb.com> | 2017-08-31 15:44:35 -0400 |
commit | ed619087e8dc51eb13578f5ebdd60f8ffee750aa (patch) | |
tree | b4e71905ab9906a7cea24873a2269de81cbe1cdd | |
parent | 2d568c4ddbe9065d92a5f0443d0c65c8f3a62a87 (diff) | |
download | mongo-ed619087e8dc51eb13578f5ebdd60f8ffee750aa.tar.gz |
jseyster/json-schema-feature-compatibility-2
If a user updates a 3.4 node to 3.6 but keeps the feature
compatibility version at 3.4, it should remain possible to be in a
replica set with 3.4 nodes or even to downgrade back to 3.4. To that
end, we ensure that is not possible to create a collection validator
with a $jsonSchema expression unless the feature compatibility version
is 3.6. A $jsonSchema validator would not replicate correctly to a 3.4
node, and its existence in the database would prevent a downgrade to
3.4.
-rw-r--r-- | jstests/multiVersion/json_schema_feature_compatibility_version.js | 123 | ||||
-rw-r--r-- | jstests/replsets/json_schema_initial_sync_with_feature_compatibility.js | 87 | ||||
-rw-r--r-- | src/mongo/db/catalog/coll_mod.cpp | 12 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection.h | 9 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection_impl.cpp | 17 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection_impl.h | 4 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection_mock.h | 3 | ||||
-rw-r--r-- | src/mongo/db/catalog/database_impl.cpp | 39 | ||||
-rw-r--r-- | src/mongo/db/matcher/copyable_match_expression.h | 2 | ||||
-rw-r--r-- | src/mongo/db/matcher/expression_parser.cpp | 10 | ||||
-rw-r--r-- | src/mongo/db/matcher/expression_parser.h | 4 | ||||
-rw-r--r-- | src/mongo/db/matcher/matcher.h | 12 | ||||
-rw-r--r-- | src/mongo/db/query/canonical_query.h | 4 |
13 files changed, 300 insertions, 26 deletions
diff --git a/jstests/multiVersion/json_schema_feature_compatibility_version.js b/jstests/multiVersion/json_schema_feature_compatibility_version.js new file mode 100644 index 00000000000..5cee64e1836 --- /dev/null +++ b/jstests/multiVersion/json_schema_feature_compatibility_version.js @@ -0,0 +1,123 @@ +// Test that mongod will not allow creationg of JSON schema validators when the +// feature compatibility version is older than 3.6. + +(function() { + "use strict"; + + const testName = "json_schema_feature_compatibility_on_startup"; + let dbpath = MongoRunner.dataPath + testName; + resetDbpath(dbpath); + + let conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "latest"}); + assert.neq(null, conn, "mongod was unable to start up"); + + let testDB = conn.getDB(testName); + assert.commandWorked(testDB.dropDatabase()); + + let adminDB = conn.getDB("admin"); + + // Explicitly set feature compatibility version 3.6. + assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "3.6"})); + + // Create a collection with a JSON Schema validator. + assert.commandWorked(testDB.createCollection( + "coll", {validator: {$jsonSchema: {properties: {foo: {type: "string"}}}}})); + let coll = testDB.coll; + + // The validator should cause this insert to fail. + assert.writeError(coll.insert({foo: 1.0}), ErrorCodes.DocumentValidationFailure); + + // Set a JSON Schema validator on an existing collection. + assert.commandWorked(testDB.runCommand( + {collMod: "coll", validator: {$jsonSchema: {properties: {bar: {type: "string"}}}}})); + + // Another failing update. + assert.writeError(coll.insert({bar: 1.0}), ErrorCodes.DocumentValidationFailure); + + // Set the feature compatibility version to 3.4. + assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "3.4"})); + + // The validator is already in place, so it should still cause this insert to fail. + assert.writeError(coll.insert({bar: 1.0}), ErrorCodes.DocumentValidationFailure); + + // Trying to create a new collection with a JSON Schema validator should fail while feature + // compatibility version is 3.4. + assert.commandFailed(testDB.createCollection("coll2", {validator: {$jsonSchema: {}}}), + ErrorCodes.InvalidOptions); + + // Trying to update a collection with a JSON Schema validator should also fail. + assert.commandFailed(testDB.runCommand({collMod: "coll", validator: {$jsonSchema: {}}}), + ErrorCodes.InvalidOptions); + + MongoRunner.stopMongod(conn); + + // If we try to start up a 3.4 mongod, it will fail, because it will not be able to parse the + // $jsonSchema validator. + conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "3.4", noCleanData: true}); + assert.eq(null, conn, "mongod 3.4 started, even with a $jsonSchema validator in place."); + + // Starting up a 3.6 mongod, however, should succeed, even though the feature compatibility + // version is still set to 3.4. + conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "latest", noCleanData: true}); + assert.neq(null, conn, "mongod was unable to start up"); + + adminDB = conn.getDB("admin"); + testDB = conn.getDB(testName); + coll = testDB.coll; + + // And the validator should still work. + assert.writeError(coll.insert({bar: 1.0}), ErrorCodes.DocumentValidationFailure); + + // Remove the validator. + assert.commandWorked(testDB.runCommand({collMod: "coll", validator: {}})); + + MongoRunner.stopMongod(conn); + + // Now, we should be able to start up a 3.4 mongod. + conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "3.4", noCleanData: true}); + assert.neq( + null, conn, "mongod 3.4 failed to start, even after we removed the $jsonSchema validator"); + + MongoRunner.stopMongod(conn); + + // The rest of the test uses mongod 3.6. + conn = MongoRunner.runMongod({dbpath: dbpath, binVersion: "latest", noCleanData: true}); + assert.neq(null, conn, "mongod was unable to start up"); + + adminDB = conn.getDB("admin"); + testDB = conn.getDB(testName); + coll = testDB.coll; + + // Set the feature compatibility version back to 3.6. + assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "3.6"})); + + // Now we should be able to create a collection with a JSON Schema validator again. + assert.commandWorked(testDB.createCollection("coll2", {validator: {$jsonSchema: {}}})); + + // And we should be able to modify a collection to have a JSON Schema validator. + assert.commandWorked(testDB.runCommand({collMod: "coll", validator: {$jsonSchema: {}}})); + + // Set the feature compatibility version to 3.4 and then restart with + // internalValidateFeaturesAsMaster=false. + assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "3.4"})); + MongoRunner.stopMongod(conn); + conn = MongoRunner.runMongod({ + dbpath: dbpath, + binVersion: "latest", + noCleanData: true, + setParameter: "internalValidateFeaturesAsMaster=false" + }); + assert.neq(null, conn, "mongod was unable to start up"); + + testDB = conn.getDB(testName); + + // Even though the feature compatibility version is 3.4, we should still be able to add a + // $jsonSchema validator, because internalValidateFeaturesAsMaster is false. + assert.commandWorked(testDB.createCollection("coll3", {validator: {$jsonSchema: {}}})); + + // We should also be able to modify a collection to have a $jsonSchema validator. + assert.commandWorked( + testDB.runCommand({collMod: "coll3", validator: {properties: {str: {type: "string"}}}})); + + MongoRunner.stopMongod(conn); +}()); diff --git a/jstests/replsets/json_schema_initial_sync_with_feature_compatibility.js b/jstests/replsets/json_schema_initial_sync_with_feature_compatibility.js new file mode 100644 index 00000000000..f875e73a00a --- /dev/null +++ b/jstests/replsets/json_schema_initial_sync_with_feature_compatibility.js @@ -0,0 +1,87 @@ +/** + * Test that a new replica set member can successfully sync a collection with a $jsonSchema + * validator, even when the replica set was downgraded to feature compatibility version 3.4. + */ + +load("jstests/replsets/rslib.js"); + +(function() { + "use strict"; + var testName = "json_schema_initial_sync_with_feature_compatibility"; + + // + // Create a single-node replica set. + // + var replTest = new ReplSetTest({name: testName, nodes: 1}); + + var conns = replTest.startSet(); + replTest.initiate(); + + var primary = replTest.getPrimary(); + var adminDB = primary.getDB("admin"); + var testDB = primary.getDB("test"); + + // + // Explicitly set the replica set to feature compatibility version 3.6. + // + var res; + assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "3.6"})); + res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); + assert.commandWorked(res); + assert.eq("3.6", res.featureCompatibilityVersion); + + // + // Create and populate a collection with a $jsonSchema validator. + // + assert.commandWorked(testDB.createCollection( + "coll", {validator: {$jsonSchema: {properties: {str: {type: "string"}}}}})); + + var bulk = testDB.coll.initializeUnorderedBulkOp(); + for (var i = 0; i < 100; i++) { + bulk.insert({date: new Date(), x: i, str: "all the talk on the market"}); + } + assert.writeOK(bulk.execute()); + + // + // Downgrade the replica set to feature compatibility version 3.4. + // + var res; + assert.commandWorked(adminDB.runCommand({setFeatureCompatibilityVersion: "3.4"})); + res = adminDB.runCommand({getParameter: 1, featureCompatibilityVersion: 1}); + assert.commandWorked(res); + assert.eq("3.4", res.featureCompatibilityVersion); + + // + // Add a new member to the replica set. + // + var secondaryDBPath = MongoRunner.dataPath + testName + "_secondary"; + resetDbpath(secondaryDBPath); + var secondary = replTest.add({dbpath: secondaryDBPath}); + replTest.reInitiate(secondary); + reconnect(primary); + reconnect(secondary); + + // + // Once the new member completes its initial sync, stop it, remove it from the replica set, and + // start it back up as an individual instance. + // + replTest.waitForState(secondary, [ReplSetTest.State.PRIMARY, ReplSetTest.State.SECONDARY]); + + replTest.stopSet(undefined /* send default signal */, true /* don't clear data directory */); + + secondary = MongoRunner.runMongod({dbpath: secondaryDBPath, noCleanData: true}); + + // + // Verify that the $jsonSchema validator synced to the new member by attempting to insert a + // document that does not validate and checking that the insert fails. + // + var secondaryDB = secondary.getDB("test"); + assert.writeError(secondaryDB.coll.insert({str: 1.0}), ErrorCodes.DocumentValidationFailure); + + // + // Verify that, even though the existing $jsonSchema validator still works, it is not possible + // to create a new $jsonSchema validator because of feature compatibility 3.4. + // + assert.commandFailed(secondaryDB.runCommand({collMod: "coll", validator: {$jsonSchema: {}}}), + ErrorCodes.InvalidOptions); +}());
\ No newline at end of file diff --git a/src/mongo/db/catalog/coll_mod.cpp b/src/mongo/db/catalog/coll_mod.cpp index d294d284bc4..373890fec77 100644 --- a/src/mongo/db/catalog/coll_mod.cpp +++ b/src/mongo/db/catalog/coll_mod.cpp @@ -169,7 +169,17 @@ StatusWith<CollModRequest> parseCollModRequest(OperationContext* opCtx, } } else if (fieldName == "validator" && !isView) { - auto statusW = coll->parseValidator(e.Obj()); + MatchExpressionParser::AllowedFeatureSet allowedFeatures = + MatchExpressionParser::kBanAllSpecialFeatures; + if (!serverGlobalParams.featureCompatibility.validateFeaturesAsMaster.load() || + serverGlobalParams.featureCompatibility.version.load() != + ServerGlobalParams::FeatureCompatibility::Version::k34) { + // Allow $jsonSchema only if the feature compatibility version is newer than 3.4. + // Note that we don't enforce this restriction on the secondary or on backup + // instances, as indicated by !validateFeaturesAsMaster. + allowedFeatures |= MatchExpressionParser::kJSONSchema; + } + auto statusW = coll->parseValidator(e.Obj(), allowedFeatures); if (!statusW.isOK()) return statusW.getStatus(); diff --git a/src/mongo/db/catalog/collection.h b/src/mongo/db/catalog/collection.h index ee44eb2d14f..df30097f6ca 100644 --- a/src/mongo/db/catalog/collection.h +++ b/src/mongo/db/catalog/collection.h @@ -315,7 +315,9 @@ public: virtual void cappedTruncateAfter(OperationContext* opCtx, RecordId end, bool inclusive) = 0; - virtual StatusWithMatchExpression parseValidator(const BSONObj& validator) const = 0; + virtual StatusWithMatchExpression parseValidator( + const BSONObj& validator, + MatchExpressionParser::AllowedFeatureSet allowedFeatures) const = 0; virtual Status setValidator(OperationContext* opCtx, BSONObj validator) = 0; @@ -638,8 +640,9 @@ public: /** * Returns a non-ok Status if validator is not legal for this collection. */ - inline StatusWithMatchExpression parseValidator(const BSONObj& validator) const { - return this->_impl().parseValidator(validator); + inline StatusWithMatchExpression parseValidator( + const BSONObj& validator, MatchExpressionParser::AllowedFeatureSet allowedFeatures) const { + return this->_impl().parseValidator(validator, allowedFeatures); } static StatusWith<ValidationLevel> parseValidationLevel(StringData); diff --git a/src/mongo/db/catalog/collection_impl.cpp b/src/mongo/db/catalog/collection_impl.cpp index 0824f877660..5896b3b9f46 100644 --- a/src/mongo/db/catalog/collection_impl.cpp +++ b/src/mongo/db/catalog/collection_impl.cpp @@ -159,7 +159,10 @@ CollectionImpl::CollectionImpl(Collection* _this_init, _indexCatalog(_this_init, this->getCatalogEntry()->getMaxAllowedIndexes()), _collator(parseCollation(opCtx, _ns, _details->getCollectionOptions(opCtx).collation)), _validatorDoc(_details->getCollectionOptions(opCtx).validator.getOwned()), - _validator(uassertStatusOK(parseValidator(_validatorDoc))), + _validator( + uassertStatusOK(parseValidator(_validatorDoc, + MatchExpressionParser::kAllowAllSpecialFeatures & + ~MatchExpressionParser::AllowedFeatures::kExpr))), _validationAction(uassertStatusOK( parseValidationAction(_details->getCollectionOptions(opCtx).validationAction))), _validationLevel(uassertStatusOK( @@ -265,7 +268,8 @@ Status CollectionImpl::checkValidation(OperationContext* opCtx, const BSONObj& d return {ErrorCodes::DocumentValidationFailure, "Document failed validation"}; } -StatusWithMatchExpression CollectionImpl::parseValidator(const BSONObj& validator) const { +StatusWithMatchExpression CollectionImpl::parseValidator( + const BSONObj& validator, MatchExpressionParser::AllowedFeatureSet allowedFeatures) const { if (validator.isEmpty()) return {nullptr}; @@ -282,7 +286,8 @@ StatusWithMatchExpression CollectionImpl::parseValidator(const BSONObj& validato << " database"}; } - auto statusWithMatcher = MatchExpressionParser::parse(validator, _collator.get()); + auto statusWithMatcher = MatchExpressionParser::parse( + validator, _collator.get(), nullptr, ExtensionsCallbackNoop(), allowedFeatures); if (!statusWithMatcher.isOK()) return statusWithMatcher.getStatus(); @@ -887,7 +892,11 @@ Status CollectionImpl::setValidator(OperationContext* opCtx, BSONObj validatorDo if (!validatorDoc.isOwned()) validatorDoc = validatorDoc.getOwned(); - auto statusWithMatcher = parseValidator(validatorDoc); + // Note that, by the time we reach this, we should have already done a pre-parse that checks for + // banned features, so we don't need to include that check again. + auto statusWithMatcher = parseValidator(validatorDoc, + MatchExpressionParser::kAllowAllSpecialFeatures & + ~MatchExpressionParser::AllowedFeatures::kExpr); if (!statusWithMatcher.isOK()) return statusWithMatcher.getStatus(); diff --git a/src/mongo/db/catalog/collection_impl.h b/src/mongo/db/catalog/collection_impl.h index 89262f9f7cc..4a66cb1a8bc 100644 --- a/src/mongo/db/catalog/collection_impl.h +++ b/src/mongo/db/catalog/collection_impl.h @@ -283,7 +283,9 @@ public: /** * Returns a non-ok Status if validator is not legal for this collection. */ - StatusWithMatchExpression parseValidator(const BSONObj& validator) const final; + StatusWithMatchExpression parseValidator( + const BSONObj& validator, + MatchExpressionParser::AllowedFeatureSet allowedFeatures) const final; static StatusWith<ValidationLevel> parseValidationLevel(StringData); static StatusWith<ValidationAction> parseValidationAction(StringData); diff --git a/src/mongo/db/catalog/collection_mock.h b/src/mongo/db/catalog/collection_mock.h index a4bb7143e31..e9ecffc144b 100644 --- a/src/mongo/db/catalog/collection_mock.h +++ b/src/mongo/db/catalog/collection_mock.h @@ -220,7 +220,8 @@ public: std::abort(); } - StatusWithMatchExpression parseValidator(const BSONObj& validator) const { + StatusWithMatchExpression parseValidator( + const BSONObj& validator, MatchExpressionParser::AllowedFeatureSet allowedFeatures) const { std::abort(); } diff --git a/src/mongo/db/catalog/database_impl.cpp b/src/mongo/db/catalog/database_impl.cpp index 8ddce6e8c5a..22cf455fd66 100644 --- a/src/mongo/db/catalog/database_impl.cpp +++ b/src/mongo/db/catalog/database_impl.cpp @@ -953,14 +953,17 @@ auto mongo::userCreateNSImpl(OperationContext* opCtx, return status; // Validate the collation, if there is one. + std::unique_ptr<CollatorInterface> collator; if (!collectionOptions.collation.isEmpty()) { - auto collator = CollatorFactoryInterface::get(opCtx->getServiceContext()) - ->makeFromBSON(collectionOptions.collation); + auto collatorWithStatus = CollatorFactoryInterface::get(opCtx->getServiceContext()) + ->makeFromBSON(collectionOptions.collation); - if (!collator.isOK()) { - return collator.getStatus(); + if (!collatorWithStatus.isOK()) { + return collatorWithStatus.getStatus(); } + collator = std::move(collatorWithStatus.getValue()); + // If the collator factory returned a non-null collator, set the collation option to the // result of serializing the collator's spec back into BSON. We do this in order to fill in // all options that the user omitted. @@ -969,8 +972,32 @@ auto mongo::userCreateNSImpl(OperationContext* opCtx, // we simply unset the "collation" from the collection options. This ensures that // collections created on versions which do not support the collation feature have the same // format for representing the simple collation as collections created on this version. - collectionOptions.collation = - collator.getValue() ? collator.getValue()->getSpec().toBSON() : BSONObj(); + collectionOptions.collation = collator ? collator->getSpec().toBSON() : BSONObj(); + } + + if (!collectionOptions.validator.isEmpty()) { + // Pre-parse the validator document to make sure there are no extensions that are not + // permitted in collection validators. + MatchExpressionParser::AllowedFeatureSet allowedFeatures = + MatchExpressionParser::kBanAllSpecialFeatures; + if (!serverGlobalParams.featureCompatibility.validateFeaturesAsMaster.load() || + serverGlobalParams.featureCompatibility.version.load() != + ServerGlobalParams::FeatureCompatibility::Version::k34) { + // $jsonSchema is only permitted when the feature compatibility version is newer + // than 3.4. Note that we don't enforce this feature compatibility check when we are on + // the secondary or on a backup instance, as indicated by !validateFeaturesAsMaster. + allowedFeatures |= MatchExpressionParser::kJSONSchema; + } + auto statusWithMatcher = MatchExpressionParser::parse(collectionOptions.validator, + collator.get(), + nullptr, + ExtensionsCallbackNoop(), + allowedFeatures); + + // We check the status of the parse to see if there are any banned features, but we don't + // actually need the result for now. + if (!statusWithMatcher.isOK()) + return statusWithMatcher.getStatus(); } status = diff --git a/src/mongo/db/matcher/copyable_match_expression.h b/src/mongo/db/matcher/copyable_match_expression.h index 8961dce131d..a1557b6f382 100644 --- a/src/mongo/db/matcher/copyable_match_expression.h +++ b/src/mongo/db/matcher/copyable_match_expression.h @@ -56,7 +56,7 @@ public: std::unique_ptr<const ExtensionsCallback> extensionsCallback = stdx::make_unique<ExtensionsCallbackNoop>(), MatchExpressionParser::AllowedFeatureSet allowedFeatures = - MatchExpressionParser::kBanAllSpecialFeatures) + MatchExpressionParser::kDefaultSpecialFeatures) : _matchAST(matchAST), _extensionsCallback(std::move(extensionsCallback)) { StatusWithMatchExpression parseResult = MatchExpressionParser::parse( _matchAST, collator, expCtx, *_extensionsCallback, allowedFeatures); diff --git a/src/mongo/db/matcher/expression_parser.cpp b/src/mongo/db/matcher/expression_parser.cpp index f945115c370..4f995fbfa4e 100644 --- a/src/mongo/db/matcher/expression_parser.cpp +++ b/src/mongo/db/matcher/expression_parser.cpp @@ -39,6 +39,7 @@ #include "mongo/bson/bsonmisc.h" #include "mongo/bson/bsonobj.h" #include "mongo/bson/bsonobjbuilder.h" +#include "mongo/db/commands/feature_compatibility_version_command_parser.h" #include "mongo/db/matcher/expression_always_boolean.h" #include "mongo/db/matcher/expression_array.h" #include "mongo/db/matcher/expression_geo.h" @@ -576,6 +577,15 @@ StatusWithMatchExpression MatchExpressionParser::_parse( return _parseTopLevelInternalSchemaSingleIntegerArgument< InternalSchemaMaxPropertiesMatchExpression>(e); } else if (mongoutils::str::equals("jsonSchema", rest)) { + if ((allowedFeatures & AllowedFeatures::kJSONSchema) == 0u) { + return Status( + ErrorCodes::BadValue, + str::stream() + << "The featureCompatiblityVersion must be 3.6 to use $jsonSchema. See " + << feature_compatibility_version::kDochubLink + << "."); + } + if (e.type() != BSONType::Object) { return {Status(ErrorCodes::TypeMismatch, "$jsonSchema must be an object")}; } diff --git a/src/mongo/db/matcher/expression_parser.h b/src/mongo/db/matcher/expression_parser.h index 75ed1a60dd7..55ef95ddf4a 100644 --- a/src/mongo/db/matcher/expression_parser.h +++ b/src/mongo/db/matcher/expression_parser.h @@ -92,11 +92,13 @@ public: kGeoNear = 1 << 1, kJavascript = 1 << 2, kExpr = 1 << 3, + kJSONSchema = 1 << 4, }; using AllowedFeatureSet = unsigned long long; static constexpr AllowedFeatureSet kBanAllSpecialFeatures = 0; static constexpr AllowedFeatureSet kAllowAllSpecialFeatures = std::numeric_limits<unsigned long long>::max(); + static constexpr AllowedFeatureSet kDefaultSpecialFeatures = AllowedFeatures::kJSONSchema; /** * Constant double representation of 2^63. @@ -122,7 +124,7 @@ public: const CollatorInterface* collator, const boost::intrusive_ptr<ExpressionContext>& expCtx = nullptr, const ExtensionsCallback& extensionsCallback = ExtensionsCallbackNoop(), - AllowedFeatureSet allowedFeatures = kBanAllSpecialFeatures) { + AllowedFeatureSet allowedFeatures = kDefaultSpecialFeatures) { // A non-null ExpressionContext is required for parsing $expr. if (!expCtx) { invariant((allowedFeatures & AllowedFeatures::kExpr) == 0u); diff --git a/src/mongo/db/matcher/matcher.h b/src/mongo/db/matcher/matcher.h index 382b0dd4e0d..4d1c8783747 100644 --- a/src/mongo/db/matcher/matcher.h +++ b/src/mongo/db/matcher/matcher.h @@ -54,12 +54,12 @@ public: /** * 'collator' must outlive the returned Matcher and any MatchExpression cloned from it. */ - explicit Matcher(const BSONObj& pattern, - const CollatorInterface* collator, - const boost::intrusive_ptr<ExpressionContext>& expCtx = nullptr, - const ExtensionsCallback& extensionsCallback = ExtensionsCallbackNoop(), - MatchExpressionParser::AllowedFeatureSet allowedFeatures = - MatchExpressionParser::kBanAllSpecialFeatures); + Matcher(const BSONObj& pattern, + const CollatorInterface* collator, + const boost::intrusive_ptr<ExpressionContext>& expCtx = nullptr, + const ExtensionsCallback& extensionsCallback = ExtensionsCallbackNoop(), + MatchExpressionParser::AllowedFeatureSet allowedFeatures = + MatchExpressionParser::kDefaultSpecialFeatures); bool matches(const BSONObj& doc, MatchDetails* details = NULL) const; diff --git a/src/mongo/db/query/canonical_query.h b/src/mongo/db/query/canonical_query.h index 54360808233..392c75ca704 100644 --- a/src/mongo/db/query/canonical_query.h +++ b/src/mongo/db/query/canonical_query.h @@ -59,7 +59,7 @@ public: const boost::intrusive_ptr<ExpressionContext>& expCtx = nullptr, const ExtensionsCallback& extensionsCallback = ExtensionsCallbackNoop(), MatchExpressionParser::AllowedFeatureSet allowedFeatures = - MatchExpressionParser::kBanAllSpecialFeatures); + MatchExpressionParser::kDefaultSpecialFeatures); /** * If parsing succeeds, returns a std::unique_ptr<CanonicalQuery> representing the parsed @@ -74,7 +74,7 @@ public: const boost::intrusive_ptr<ExpressionContext>& expCtx = nullptr, const ExtensionsCallback& extensionsCallback = ExtensionsCallbackNoop(), MatchExpressionParser::AllowedFeatureSet allowedFeatures = - MatchExpressionParser::kBanAllSpecialFeatures); + MatchExpressionParser::kDefaultSpecialFeatures); /** * For testing or for internal clients to use. |