summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog
diff options
context:
space:
mode:
authorTess Avitabile <tess.avitabile@mongodb.com>2016-05-25 15:26:24 -0400
committerTess Avitabile <tess.avitabile@mongodb.com>2016-06-02 13:27:48 -0400
commit0d2f72f5471f7c0f283ceea314c48d2e25d7d556 (patch)
tree9bd0d6229b343c81c4939cc49bdcf85836c6c41f /src/mongo/db/catalog
parent4c79077a39e036a6ddac5fadfbe1513348a04e35 (diff)
downloadmongo-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.cpp47
-rw-r--r--src/mongo/db/catalog/index_catalog_entry.cpp23
-rw-r--r--src/mongo/db/catalog/index_catalog_entry.h2
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