diff options
Diffstat (limited to 'src/mongo/db/views/durable_view_catalog.cpp')
| -rw-r--r-- | src/mongo/db/views/durable_view_catalog.cpp | 121 |
1 files changed, 41 insertions, 80 deletions
diff --git a/src/mongo/db/views/durable_view_catalog.cpp b/src/mongo/db/views/durable_view_catalog.cpp index e5281a8c63c..c96b7af6672 100644 --- a/src/mongo/db/views/durable_view_catalog.cpp +++ b/src/mongo/db/views/durable_view_catalog.cpp @@ -47,7 +47,6 @@ #include "mongo/db/operation_context.h" #include "mongo/db/storage/record_data.h" #include "mongo/db/tenant_database_name.h" -#include "mongo/db/views/view_catalog_helpers.h" #include "mongo/logv2/log.h" #include "mongo/stdx/unordered_set.h" #include "mongo/util/assert_util.h" @@ -55,57 +54,6 @@ namespace mongo { -namespace { -void validateViewDefinitionBSON(OperationContext* opCtx, - const BSONObj& viewDefinition, - StringData dbName) { - // Internal callers should always pass in a valid 'dbName' against which to compare the - // 'viewDefinition'. - invariant(NamespaceString::validDBName(dbName)); - - bool valid = true; - - for (const BSONElement& e : viewDefinition) { - std::string name(e.fieldName()); - valid &= name == "_id" || name == "viewOn" || name == "pipeline" || name == "collation" || - name == "timeseries"; - } - - const auto viewName = viewDefinition["_id"].str(); - const auto viewNameIsValid = NamespaceString::validCollectionComponent(viewName) && - NamespaceString::validDBName(nsToDatabaseSubstring(viewName)); - valid &= viewNameIsValid; - - // Only perform validation via NamespaceString if the collection name has been determined to - // be valid. If not valid then the NamespaceString constructor will uassert. - if (viewNameIsValid) { - NamespaceString viewNss(viewName); - valid &= viewNss.isValid() && viewNss.db() == dbName; - } - - valid &= NamespaceString::validCollectionName(viewDefinition["viewOn"].str()); - - const bool hasPipeline = viewDefinition.hasField("pipeline"); - valid &= hasPipeline; - if (hasPipeline) { - valid &= viewDefinition["pipeline"].type() == mongo::Array; - } - - valid &= (!viewDefinition.hasField("collation") || - viewDefinition["collation"].type() == BSONType::Object); - - valid &= !viewDefinition.hasField("timeseries") || - viewDefinition["timeseries"].type() == BSONType::Object; - - uassert(ErrorCodes::InvalidViewDefinition, - str::stream() << "found invalid view definition " << viewDefinition["_id"] - << " while reading '" - << NamespaceString(dbName, NamespaceString::kSystemDotViewsCollectionName) - << "'", - valid); -} -} // namespace - // DurableViewCatalog void DurableViewCatalog::onExternalChange(OperationContext* opCtx, const NamespaceString& name) { @@ -120,30 +68,6 @@ void DurableViewCatalog::onExternalChange(OperationContext* opCtx, const Namespa catalog->reloadViews(opCtx, name.db()).ignore(); } -Status DurableViewCatalog::onExternalInsert(OperationContext* opCtx, - const BSONObj& doc, - const NamespaceString& name) { - try { - validateViewDefinitionBSON(opCtx, doc, name.db()); - } catch (const DBException& e) { - return e.toStatus(); - } - - auto catalog = CollectionCatalog::get(opCtx); - NamespaceString viewName(doc.getStringField("_id")); - NamespaceString viewOn(name.db(), doc.getStringField("viewOn")); - BSONArray pipeline(doc.getObjectField("pipeline")); - BSONObj collation(doc.getObjectField("collation")); - - return catalog->createView(opCtx, - viewName, - viewOn, - pipeline, - collation, - view_catalog_helpers::validatePipeline, - CollectionCatalog::ViewUpsertMode::kAlreadyDurableView); -} - void DurableViewCatalog::onSystemViewsCollectionDrop(OperationContext* opCtx, const NamespaceString& name) { dassert(opCtx->lockState()->isDbLockedForMode(name.db(), MODE_IX)); @@ -203,9 +127,9 @@ void DurableViewCatalogImpl::_iterate(OperationContext* opCtx, try { viewDefinition = _validateViewDefinition(opCtx, record->data); uassertStatusOK(callback(viewDefinition)); - } catch (const ExceptionFor<ErrorCodes::InvalidViewDefinition>&) { + } catch (const ExceptionFor<ErrorCodes::InvalidViewDefinition>& ex) { if (lookupBehavior == ViewCatalogLookupBehavior::kValidateViews) { - throw; + throw ex; } } } @@ -218,9 +142,46 @@ BSONObj DurableViewCatalogImpl::_validateViewDefinition(OperationContext* opCtx, // decimal data even if decimal is disabled. fassert(40224, validateBSON(recordData.data(), recordData.size())); BSONObj viewDefinition = recordData.toBson(); - std::string dbName(_db->name().dbName()); - validateViewDefinitionBSON(opCtx, viewDefinition, dbName); + bool valid = true; + + for (const BSONElement& e : viewDefinition) { + std::string name(e.fieldName()); + valid &= name == "_id" || name == "viewOn" || name == "pipeline" || name == "collation" || + name == "timeseries"; + } + + const auto viewName = viewDefinition["_id"].str(); + const auto viewNameIsValid = NamespaceString::validCollectionComponent(viewName) && + NamespaceString::validDBName(nsToDatabaseSubstring(viewName)); + valid &= viewNameIsValid; + + // Only perform validation via NamespaceString if the collection name has been determined to + // be valid. If not valid then the NamespaceString constructor will uassert. + if (viewNameIsValid) { + NamespaceString viewNss(viewName); + valid &= viewNss.isValid() && viewNss.db() == _db->name().dbName(); + } + + valid &= NamespaceString::validCollectionName(viewDefinition["viewOn"].str()); + + const bool hasPipeline = viewDefinition.hasField("pipeline"); + valid &= hasPipeline; + if (hasPipeline) { + valid &= viewDefinition["pipeline"].type() == mongo::Array; + } + + valid &= (!viewDefinition.hasField("collation") || + viewDefinition["collation"].type() == BSONType::Object); + + valid &= !viewDefinition.hasField("timeseries") || + viewDefinition["timeseries"].type() == BSONType::Object; + + uassert(ErrorCodes::InvalidViewDefinition, + str::stream() << "found invalid view definition " << viewDefinition["_id"] + << " while reading '" << _db->getSystemViewsName() << "'", + valid); + return viewDefinition; } |
