diff options
author | Tess Avitabile <tess.avitabile@mongodb.com> | 2016-05-25 15:26:24 -0400 |
---|---|---|
committer | Tess Avitabile <tess.avitabile@mongodb.com> | 2016-06-02 13:27:48 -0400 |
commit | 0d2f72f5471f7c0f283ceea314c48d2e25d7d556 (patch) | |
tree | 9bd0d6229b343c81c4939cc49bdcf85836c6c41f /src/mongo/db/catalog | |
parent | 4c79077a39e036a6ddac5fadfbe1513348a04e35 (diff) | |
download | mongo-0d2f72f5471f7c0f283ceea314c48d2e25d7d556.tar.gz |
SERVER-23618 Add collation support for partial indexes
Diffstat (limited to 'src/mongo/db/catalog')
-rw-r--r-- | src/mongo/db/catalog/index_catalog.cpp | 47 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_catalog_entry.cpp | 23 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_catalog_entry.h | 2 |
3 files changed, 37 insertions, 35 deletions
diff --git a/src/mongo/db/catalog/index_catalog.cpp b/src/mongo/db/catalog/index_catalog.cpp index 58efa054129..b1ed77750ed 100644 --- a/src/mongo/db/catalog/index_catalog.cpp +++ b/src/mongo/db/catalog/index_catalog.cpp @@ -542,6 +542,28 @@ Status IndexCatalog::_isSpecOk(OperationContext* txn, const BSONObj& spec) const << keyStatus.reason()); } + std::unique_ptr<CollatorInterface> collator; + BSONElement collationElement = spec.getField("collation"); + if (collationElement) { + string pluginName = IndexNames::findPluginName(key); + if ((pluginName != IndexNames::BTREE) && (pluginName != IndexNames::GEO_2DSPHERE) && + (pluginName != IndexNames::HASHED)) { + return Status(ErrorCodes::CannotCreateIndex, + str::stream() << "\"collation\" not supported for index type " + << pluginName); + } + if (collationElement.type() != BSONType::Object) { + return Status(ErrorCodes::CannotCreateIndex, + "\"collation\" for an index must be a document"); + } + auto statusWithCollator = CollatorFactoryInterface::get(txn->getServiceContext()) + ->makeFromBSON(collationElement.Obj()); + if (!statusWithCollator.isOK()) { + return statusWithCollator.getStatus(); + } + collator = std::move(statusWithCollator.getValue()); + } + const bool isSparse = spec["sparse"].trueValue(); // Ensure if there is a filter, its valid. @@ -556,9 +578,10 @@ Status IndexCatalog::_isSpecOk(OperationContext* txn, const BSONObj& spec) const return Status(ErrorCodes::CannotCreateIndex, "\"partialFilterExpression\" for an index must be a document"); } - // TODO SERVER-23618: pass the appropriate CollatorInterface* instead of nullptr. + + // The collator must outlive the constructed MatchExpression. StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse( - filterElement.Obj(), ExtensionsCallbackDisallowExtensions(), nullptr); + filterElement.Obj(), ExtensionsCallbackDisallowExtensions(), collator.get()); if (!statusWithMatcher.isOK()) { return statusWithMatcher.getStatus(); } @@ -570,26 +593,6 @@ Status IndexCatalog::_isSpecOk(OperationContext* txn, const BSONObj& spec) const } } - BSONElement collationElement = spec.getField("collation"); - if (collationElement) { - string pluginName = IndexNames::findPluginName(key); - if ((pluginName != IndexNames::BTREE) && (pluginName != IndexNames::GEO_2DSPHERE) && - (pluginName != IndexNames::HASHED)) { - return Status(ErrorCodes::CannotCreateIndex, - str::stream() << "\"collation\" not supported for index type " - << pluginName); - } - if (collationElement.type() != BSONType::Object) { - return Status(ErrorCodes::CannotCreateIndex, - "\"collation\" for an index must be a document"); - } - auto statusWithCollator = CollatorFactoryInterface::get(txn->getServiceContext()) - ->makeFromBSON(collationElement.Obj()); - if (!statusWithCollator.isOK()) { - return statusWithCollator.getStatus(); - } - } - if (IndexDescriptor::isIdIndexPattern(key)) { BSONElement uniqueElt = spec["unique"]; if (uniqueElt && !uniqueElt.trueValue()) { diff --git a/src/mongo/db/catalog/index_catalog_entry.cpp b/src/mongo/db/catalog/index_catalog_entry.cpp index ff52a47b089..0ac3ac5665e 100644 --- a/src/mongo/db/catalog/index_catalog_entry.cpp +++ b/src/mongo/db/catalog/index_catalog_entry.cpp @@ -95,27 +95,26 @@ IndexCatalogEntry::IndexCatalogEntry(OperationContext* txn, _indexTracksPathLevelMultikeyInfo = !_indexMultikeyPaths.empty(); } + if (BSONElement collationElement = _descriptor->getInfoElement("collation")) { + invariant(collationElement.isABSONObj()); + BSONObj collation = collationElement.Obj(); + auto statusWithCollator = + CollatorFactoryInterface::get(txn->getServiceContext())->makeFromBSON(collation); + invariantOK(statusWithCollator.getStatus()); + _collator = std::move(statusWithCollator.getValue()); + } + if (BSONElement filterElement = _descriptor->getInfoElement("partialFilterExpression")) { invariant(filterElement.isABSONObj()); BSONObj filter = filterElement.Obj(); - // TODO SERVER-23618: pass the appropriate CollatorInterface* instead of nullptr. - StatusWithMatchExpression statusWithMatcher = - MatchExpressionParser::parse(filter, ExtensionsCallbackDisallowExtensions(), nullptr); + StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse( + filter, ExtensionsCallbackDisallowExtensions(), _collator.get()); // this should be checked in create, so can blow up here invariantOK(statusWithMatcher.getStatus()); _filterExpression = std::move(statusWithMatcher.getValue()); LOG(2) << "have filter expression for " << _ns << " " << _descriptor->indexName() << " " << filter; } - - if (BSONElement collationElement = _descriptor->getInfoElement("collation")) { - invariant(collationElement.isABSONObj()); - BSONObj collation = collationElement.Obj(); - auto statusWithCollator = - CollatorFactoryInterface::get(txn->getServiceContext())->makeFromBSON(collation); - invariantOK(statusWithCollator.getStatus()); - _collator = std::move(statusWithCollator.getValue()); - } } IndexCatalogEntry::~IndexCatalogEntry() { diff --git a/src/mongo/db/catalog/index_catalog_entry.h b/src/mongo/db/catalog/index_catalog_entry.h index eb86ea2905c..64f72822404 100644 --- a/src/mongo/db/catalog/index_catalog_entry.h +++ b/src/mongo/db/catalog/index_catalog_entry.h @@ -181,8 +181,8 @@ private: // Owned here. HeadManager* _headManager; - std::unique_ptr<MatchExpression> _filterExpression; std::unique_ptr<CollatorInterface> _collator; + std::unique_ptr<MatchExpression> _filterExpression; // cached stuff |