diff options
-rw-r--r-- | jstests/core/index_partial_create_drop.js | 8 | ||||
-rw-r--r-- | src/mongo/db/index_builds_coordinator.cpp | 22 | ||||
-rw-r--r-- | src/mongo/db/index_builds_coordinator.h | 4 |
3 files changed, 13 insertions, 21 deletions
diff --git a/jstests/core/index_partial_create_drop.js b/jstests/core/index_partial_create_drop.js index 706e787ee71..24a3d29fac4 100644 --- a/jstests/core/index_partial_create_drop.js +++ b/jstests/core/index_partial_create_drop.js @@ -42,11 +42,11 @@ assert.commandFailed( assert.commandFailed(coll.createIndex( {x: 1}, {partialFilterExpression: {$expr: {$eq: [{$trim: {input: "$x"}}, "hi"]}}})); -// Only top-level $and is permitted, but by normalizing the input filter we absorb the child $and. -assert.commandWorked(coll.createIndex({x: 1}, { +// Only top-level $and is permitted in a partial filter expression. +assert.commandFailedWithCode(coll.createIndex({x: 1}, { partialFilterExpression: {$and: [{$and: [{x: {$lt: 2}}, {x: {$gt: 0}}]}, {x: {$exists: true}}]} -})); -assert.commandWorked(coll.dropIndexes()); +}), + ErrorCodes.CannotCreateIndex); for (var i = 0; i < 10; i++) { assert.commandWorked(coll.insert({x: i, a: i})); diff --git a/src/mongo/db/index_builds_coordinator.cpp b/src/mongo/db/index_builds_coordinator.cpp index 39dd76d54cd..59cf52abfcf 100644 --- a/src/mongo/db/index_builds_coordinator.cpp +++ b/src/mongo/db/index_builds_coordinator.cpp @@ -2757,7 +2757,7 @@ std::vector<BSONObj> IndexBuildsCoordinator::prepareSpecListForCreate( return indexSpecs; } - // Normalize the specs' collations, wildcard projections, and partial filters as applicable. + // Normalize the specs' collations, wildcard projections, and any other fields as applicable. auto normalSpecs = normalizeIndexSpecs(opCtx, collection, indexSpecs); // Remove any index specifications which already exist in the catalog. @@ -2791,20 +2791,12 @@ std::vector<BSONObj> IndexBuildsCoordinator::normalizeIndexSpecs( auto normalSpecs = uassertStatusOK(collection->addCollationDefaultsToIndexSpecsForCreate(opCtx, indexSpecs)); - // If the index spec has a partialFilterExpression, we normalize it by parsing to an optimized, - // sorted MatchExpression tree, re-serialize it to BSON, and add it back into the index spec. - const auto expCtx = make_intrusive<ExpressionContext>(opCtx, nullptr, collection->ns()); - std::transform(normalSpecs.begin(), normalSpecs.end(), normalSpecs.begin(), [&](auto& spec) { - const auto kPartialFilterName = IndexDescriptor::kPartialFilterExprFieldName; - auto partialFilterExpr = spec.getObjectField(kPartialFilterName); - if (partialFilterExpr.isEmpty()) { - return spec; - } - // Parse, optimize and sort the MatchExpression to reduce it to its normalized form. - // Serialize the normalized filter back into the index spec before returning. - auto partialFilter = MatchExpressionParser::parseAndNormalize(partialFilterExpr, expCtx); - return spec.addField(BSON(kPartialFilterName << partialFilter->serialize()).firstElement()); - }); + // We choose not to normalize the spec's partialFilterExpression at this point, if it exists. + // Doing so often reduces the legibility of the filter to the end-user, and makes it difficult + // for clients to validate (via the listIndexes output) whether a given partialFilterExpression + // is equivalent to the filter that they originally submitted. Omitting this normalization does + // not impact our internal index comparison semantics, since we compare based on the parsed + // MatchExpression trees rather than the serialized BSON specs. See SERVER-54357. // If any of the specs describe wildcard indexes, normalize the wildcard projections if present. // This will change all specs of the form {"a.b.c": 1} to normalized form {a: {b: {c : 1}}}. diff --git a/src/mongo/db/index_builds_coordinator.h b/src/mongo/db/index_builds_coordinator.h index 2fd4f1bb0d8..cf73da60d78 100644 --- a/src/mongo/db/index_builds_coordinator.h +++ b/src/mongo/db/index_builds_coordinator.h @@ -445,8 +445,8 @@ public: * complete collation spec in cases where the index spec specifies a collation, and will add * the collection-default collation, if present, in cases where collation is omitted. If the * index spec omits the collation and the collection does not have a default, the collation - * field is omitted from the spec. This function also converts 'wildcardProjection' and - * 'partialFilterExpression' to canonical form in any cases where they exist. + * field is omitted from the spec. This function also converts the 'wildcardProjection' to + * canonical form in any cases where it exists. * * If 'collection' is null, no changes are made to the input specs. * |