From 439df4c3bdff0194cff402a6268a9bdb9de44a7a Mon Sep 17 00:00:00 2001 From: David Storch Date: Mon, 23 May 2016 17:55:01 -0400 Subject: SERVER-23945 make IndexCatalog::_fixIndexSpec() use Status instead of throwing --- src/mongo/db/fts/fts_spec.cpp | 137 ++++++++++++++++++++++++++++-------------- 1 file changed, 92 insertions(+), 45 deletions(-) (limited to 'src/mongo/db/fts/fts_spec.cpp') diff --git a/src/mongo/db/fts/fts_spec.cpp b/src/mongo/db/fts/fts_spec.cpp index 5663d338bc6..05248d157b7 100644 --- a/src/mongo/db/fts/fts_spec.cpp +++ b/src/mongo/db/fts/fts_spec.cpp @@ -259,14 +259,17 @@ void _addFTSStuff(BSONObjBuilder* b) { b->append("_ftsx", 1); } -void verifyFieldNameNotReserved(StringData s) { - uassert(17289, - "text index with reserved fields _fts/_ftsx not allowed", - s != "_fts" && s != "_ftsx"); +Status verifyFieldNameNotReserved(StringData s) { + if (s == "_fts" || s == "_ftsx") { + return {ErrorCodes::CannotCreateIndex, + "text index with reserved fields _fts/_ftsx not allowed"}; + } + + return Status::OK(); } } -BSONObj FTSSpec::fixSpec(const BSONObj& spec) { +StatusWith FTSSpec::fixSpec(const BSONObj& spec) { if (spec["textIndexVersion"].numberInt() == TEXT_INDEX_VERSION_1) { return _fixSpecV1(spec); } @@ -284,11 +287,15 @@ BSONObj FTSSpec::fixSpec(const BSONObj& spec) { while (i.more()) { BSONElement e = i.next(); if (str::equals(e.fieldName(), "_fts")) { - uassert(17271, "expecting _fts:\"text\"", INDEX_NAME == e.valuestrsafe()); + if (INDEX_NAME != e.valuestrsafe()) { + return {ErrorCodes::CannotCreateIndex, "expecting _fts:\"text\""}; + } addedFtsStuff = true; b.append(e); } else if (str::equals(e.fieldName(), "_ftsx")) { - uassert(17272, "expecting _ftsx:1", e.numberInt() == 1); + if (e.numberInt() != 1) { + return {ErrorCodes::CannotCreateIndex, "expecting _ftsx:1"}; + } b.append(e); } else if (e.type() == String && INDEX_NAME == e.valuestr()) { if (!addedFtsStuff) { @@ -298,9 +305,10 @@ BSONObj FTSSpec::fixSpec(const BSONObj& spec) { m[e.fieldName()] = 1; } else { - uassert(17273, - "expected value 1 or -1 for non-text key in compound index", - e.numberInt() == 1 || e.numberInt() == -1); + if (e.numberInt() != 1 && e.numberInt() != -1) { + return {ErrorCodes::CannotCreateIndex, + "expected value 1 or -1 for non-text key in compound index"}; + } b.append(e); } } @@ -317,29 +325,50 @@ BSONObj FTSSpec::fixSpec(const BSONObj& spec) { // extraBefore fields while (String != e.type()) { - verifyFieldNameNotReserved(e.fieldNameStringData()); - verify(i.more()); + Status notReservedStatus = verifyFieldNameNotReserved(e.fieldNameStringData()); + if (!notReservedStatus.isOK()) { + return notReservedStatus; + } + + if (!i.more()) { + return {ErrorCodes::CannotCreateIndex, + "expected additional fields in text index key pattern"}; + } + e = i.next(); } // text fields bool alreadyFixed = str::equals(e.fieldName(), "_fts"); if (alreadyFixed) { - uassert(17288, "expected _ftsx after _fts", i.more()); + if (!i.more()) { + return {ErrorCodes::CannotCreateIndex, "expected _ftsx after _fts"}; + } e = i.next(); - uassert(17274, "expected _ftsx after _fts", str::equals(e.fieldName(), "_ftsx")); + if (!str::equals(e.fieldName(), "_ftsx")) { + return {ErrorCodes::CannotCreateIndex, "expected _ftsx after _fts"}; + } e = i.next(); } else { do { - verifyFieldNameNotReserved(e.fieldNameStringData()); + Status notReservedStatus = verifyFieldNameNotReserved(e.fieldNameStringData()); + if (!notReservedStatus.isOK()) { + return notReservedStatus; + } e = i.next(); } while (!e.eoo() && e.type() == String); } // extraAfterFields while (!e.eoo()) { - uassert(17389, "'text' fields in index must all be adjacent", e.type() != String); - verifyFieldNameNotReserved(e.fieldNameStringData()); + if (e.type() == BSONType::String) { + return {ErrorCodes::CannotCreateIndex, + "'text' fields in index must all be adjacent"}; + } + Status notReservedStatus = verifyFieldNameNotReserved(e.fieldNameStringData()); + if (!notReservedStatus.isOK()) { + return notReservedStatus; + } e = i.next(); } } @@ -349,36 +378,50 @@ BSONObj FTSSpec::fixSpec(const BSONObj& spec) { BSONObjIterator i(spec["weights"].Obj()); while (i.more()) { BSONElement e = i.next(); - uassert(17283, "weight for text index needs numeric type", e.isNumber()); + if (!e.isNumber()) { + return {ErrorCodes::CannotCreateIndex, "weight for text index needs numeric type"}; + } m[e.fieldName()] = e.numberInt(); } } else if (spec["weights"].str() == WILDCARD) { m[WILDCARD] = 1; } else if (!spec["weights"].eoo()) { - uasserted(17284, "text index option 'weights' must be an object"); + return {ErrorCodes::CannotCreateIndex, "text index option 'weights' must be an object"}; } - uassert(28823, "text index option 'weights' must specify fields or the wildcard", !m.empty()); + if (m.empty()) { + return {ErrorCodes::CannotCreateIndex, + "text index option 'weights' must specify fields or the wildcard"}; + } BSONObj weights; { BSONObjBuilder b; for (map::iterator i = m.begin(); i != m.end(); ++i) { - uassert(16674, - str::stream() << "text index weight must be in the exclusive interval (0," - << MAX_WORD_WEIGHT << ") but found: " << i->second, - i->second > 0 && i->second < MAX_WORD_WEIGHT); + if (i->second <= 0 || i->second >= MAX_WORD_WEIGHT) { + return {ErrorCodes::CannotCreateIndex, + str::stream() << "text index weight must be in the exclusive interval (0," + << MAX_WORD_WEIGHT << ") but found: " << i->second}; + } // Verify weight refers to a valid field. if (i->first != "$**") { FieldRef keyField(i->first); - uassert(17294, "weight cannot be on an empty field", keyField.numParts() != 0); + if (keyField.numParts() == 0) { + return {ErrorCodes::CannotCreateIndex, "weight cannot be on an empty field"}; + } + for (size_t partNum = 0; partNum < keyField.numParts(); partNum++) { StringData part = keyField.getPart(partNum); - uassert(17291, "weight cannot have empty path component", !part.empty()); - uassert(17292, - "weight cannot have path component with $ prefix", - !part.startsWith("$")); + if (part.empty()) { + return {ErrorCodes::CannotCreateIndex, + "weight cannot have empty path component"}; + } + + if (part.startsWith("$")) { + return {ErrorCodes::CannotCreateIndex, + "weight cannot have path component with $ prefix"}; + } } } @@ -391,22 +434,22 @@ BSONObj FTSSpec::fixSpec(const BSONObj& spec) { string default_language(default_language_elt.str()); if (default_language_elt.eoo()) { default_language = moduleDefaultLanguage; - } else { - uassert( - 17263, "default_language needs a string type", default_language_elt.type() == String); + } else if (default_language_elt.type() != BSONType::String) { + return {ErrorCodes::CannotCreateIndex, "default_language needs a string type"}; + } + + if (!FTSLanguage::make(default_language, TEXT_INDEX_VERSION_3).getStatus().isOK()) { + return {ErrorCodes::CannotCreateIndex, "default_language is not valid"}; } - uassert(17264, - "default_language is not valid", - FTSLanguage::make(default_language, TEXT_INDEX_VERSION_3).getStatus().isOK()); BSONElement language_override_elt = spec["language_override"]; string language_override(language_override_elt.str()); if (language_override_elt.eoo()) { language_override = "language"; - } else { - uassert(17136, - "language_override is not valid", - language_override_elt.type() == String && validateOverride(language_override)); + } else if (language_override_elt.type() != BSONType::String) { + return {ErrorCodes::CannotCreateIndex, "language_override must be a string"}; + } else if (!validateOverride(language_override)) { + return {ErrorCodes::CannotCreateIndex, "language_override is not valid"}; } int version = -1; @@ -430,13 +473,17 @@ BSONObj FTSSpec::fixSpec(const BSONObj& spec) { } else if (str::equals(e.fieldName(), "v")) { version = e.numberInt(); } else if (str::equals(e.fieldName(), "textIndexVersion")) { - uassert(17293, "text index option 'textIndexVersion' must be a number", e.isNumber()); - textIndexVersion = e.numberInt(); - uassert(16730, - str::stream() << "bad textIndexVersion: " << textIndexVersion, - textIndexVersion == TEXT_INDEX_VERSION_2 || - textIndexVersion == TEXT_INDEX_VERSION_3); // supported indexes + if (!e.isNumber()) { + return {ErrorCodes::CannotCreateIndex, + "text index option 'textIndexVersion' must be a number"}; + } + textIndexVersion = e.numberInt(); + if (textIndexVersion != TEXT_INDEX_VERSION_2 && + textIndexVersion != TEXT_INDEX_VERSION_3) { + return {ErrorCodes::CannotCreateIndex, + str::stream() << "bad textIndexVersion: " << textIndexVersion}; + } } else { b.append(e); } -- cgit v1.2.1