diff options
author | Maddie Zechar <mez2113@columbia.edu> | 2021-09-28 21:41:31 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-09-28 22:05:50 +0000 |
commit | 48409b32dc3e79e33272f9c34fcbc8eff8b6d0a9 (patch) | |
tree | 108cc0948c4ded802b213e0795d40d9b5ee23c64 /src/mongo/db | |
parent | 24d3bd41ce7c07c32852c334b52e4b3107136723 (diff) | |
download | mongo-48409b32dc3e79e33272f9c34fcbc8eff8b6d0a9.tar.gz |
SERVER-54597: Allow users to specify non-default collation on TS
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/commands/run_aggregate.cpp | 17 | ||||
-rw-r--r-- | src/mongo/db/views/view_catalog.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/views/view_catalog.h | 11 | ||||
-rw-r--r-- | src/mongo/db/views/view_catalog_test.cpp | 8 |
4 files changed, 36 insertions, 15 deletions
diff --git a/src/mongo/db/commands/run_aggregate.cpp b/src/mongo/db/commands/run_aggregate.cpp index 81d0b66e25a..23099af5e82 100644 --- a/src/mongo/db/commands/run_aggregate.cpp +++ b/src/mongo/db/commands/run_aggregate.cpp @@ -312,7 +312,7 @@ StatusWith<StringMap<ExpressionContext::ResolvedNamespace>> resolveInvolvedNames // If 'ns' refers to a view namespace, then we resolve its definition. auto resolveViewDefinition = [&](const NamespaceString& ns, std::shared_ptr<const ViewCatalog> vcp) -> Status { - auto resolvedView = vcp->resolveView(opCtx, ns); + auto resolvedView = vcp->resolveView(opCtx, ns, boost::none); if (!resolvedView.isOK()) { return resolvedView.getStatus().withContext( str::stream() << "Failed to resolve view '" << involvedNs.ns()); @@ -417,7 +417,7 @@ Status collatorCompatibleWithPipeline(OperationContext* opCtx, } if (!CollatorInterface::collatorsMatch(view->defaultCollator(), collator)) { return {ErrorCodes::OptionNotSupportedOnView, - str::stream() << "Cannot override default collation of view " + str::stream() << "Cannot override a view's default collation" << potentialViewNs.ns()}; } } @@ -681,16 +681,23 @@ Status runAggregate(OperationContext* opCtx, if (!request.getCollation().get_value_or(BSONObj()).isEmpty()) { invariant(collatorToUse); // Should already be resolved at this point. if (!CollatorInterface::collatorsMatch(ctx->getView()->defaultCollator(), - collatorToUse->get())) { + collatorToUse->get()) && + !ctx->getView()->timeseries()) { + return {ErrorCodes::OptionNotSupportedOnView, "Cannot override a view's default collation"}; } } - + // Queries on timeseries views may specify non-default collation whereas queries + // on all other types of views must match the default collator (the collation use + // to originally create that collections). Thus in the case of operations on TS + // views, we use the request's collation. + auto timeSeriesCollator = + ctx->getView()->timeseries() ? request.getCollation() : boost::none; auto resolvedView = uassertStatusOK(DatabaseHolder::get(opCtx) ->getViewCatalog(opCtx, nss.db()) - ->resolveView(opCtx, nss)); + ->resolveView(opCtx, nss, timeSeriesCollator)); // With the view & collation resolved, we can relinquish locks. ctx.reset(); diff --git a/src/mongo/db/views/view_catalog.cpp b/src/mongo/db/views/view_catalog.cpp index e84d0c0fa69..84e0f7b46a8 100644 --- a/src/mongo/db/views/view_catalog.cpp +++ b/src/mongo/db/views/view_catalog.cpp @@ -714,8 +714,10 @@ std::shared_ptr<const ViewDefinition> ViewCatalog::lookupWithoutValidatingDurabl return _lookup(opCtx, ns, ViewCatalogLookupBehavior::kAllowInvalidDurableViews); } -StatusWith<ResolvedView> ViewCatalog::resolveView(OperationContext* opCtx, - const NamespaceString& nss) const { +StatusWith<ResolvedView> ViewCatalog::resolveView( + OperationContext* opCtx, + const NamespaceString& nss, + boost::optional<BSONObj> timeSeriesCollator) const { _requireValidCatalog(); // Keep looping until the resolution completes. If the catalog is invalidated during the @@ -765,8 +767,13 @@ StatusWith<ResolvedView> ViewCatalog::resolveView(OperationContext* opCtx, resolvedNss = &view->viewOn(); dependencyChain.push_back(*resolvedNss); if (!collation) { - collation = view->defaultCollator() ? view->defaultCollator()->getSpec().toBSON() - : CollationSpec::kSimpleSpec; + if (timeSeriesCollator) { + collation = *timeSeriesCollator; + } else { + collation = view->defaultCollator() + ? view->defaultCollator()->getSpec().toBSON() + : CollationSpec::kSimpleSpec; + } } // Prepend the underlying view's pipeline to the current working pipeline. diff --git a/src/mongo/db/views/view_catalog.h b/src/mongo/db/views/view_catalog.h index 0903fb46cb3..b118c532c4c 100644 --- a/src/mongo/db/views/view_catalog.h +++ b/src/mongo/db/views/view_catalog.h @@ -136,8 +136,15 @@ public: * Resolve the views on 'nss', transforming the pipeline appropriately. This function returns a * fully-resolved view definition containing the backing namespace, the resolved pipeline and * the collation to use for the operation. - */ - StatusWith<ResolvedView> resolveView(OperationContext* opCtx, const NamespaceString& nss) const; + * + * With SERVER-54597, we allow queries on timeseries collections *only* to specify non-default + * collations. So in the case of queries on timeseries collections, we create a ResolvedView + * with the request's collation (timeSeriesCollator) rather than the collection's default + * collator. + */ + StatusWith<ResolvedView> resolveView(OperationContext* opCtx, + const NamespaceString& nss, + boost::optional<BSONObj> timeseriesCollator) const; /** * Usage statistics about this view catalog. diff --git a/src/mongo/db/views/view_catalog_test.cpp b/src/mongo/db/views/view_catalog_test.cpp index 8dedba3d753..f468f5feac9 100644 --- a/src/mongo/db/views/view_catalog_test.cpp +++ b/src/mongo/db/views/view_catalog_test.cpp @@ -673,7 +673,7 @@ TEST_F(ViewCatalogFixture, ResolveViewCorrectPipeline) { ASSERT_OK(createView(operationContext(), view3, view2, pipeline3.arr(), emptyCollation)); Lock::DBLock dbLock(operationContext(), "db", MODE_IX); - auto resolvedView = getViewCatalog()->resolveView(operationContext(), view3); + auto resolvedView = getViewCatalog()->resolveView(operationContext(), view3, boost::none); ASSERT(resolvedView.isOK()); std::vector<BSONObj> expected = {BSON("$match" << BSON("foo" << 1)), @@ -693,8 +693,8 @@ TEST_F(ViewCatalogFixture, ResolveViewOnCollectionNamespace) { const NamespaceString collectionNamespace("db.coll"); Lock::DBLock dbLock(operationContext(), "db", MODE_IS); - auto resolvedView = - uassertStatusOK(getViewCatalog()->resolveView(operationContext(), collectionNamespace)); + auto resolvedView = uassertStatusOK( + getViewCatalog()->resolveView(operationContext(), collectionNamespace, boost::none)); ASSERT_EQ(resolvedView.getNamespace(), collectionNamespace); ASSERT_EQ(resolvedView.getPipeline().size(), 0U); @@ -717,7 +717,7 @@ TEST_F(ViewCatalogFixture, ResolveViewCorrectlyExtractsDefaultCollation) { ASSERT_OK(createView(operationContext(), view2, view1, pipeline2.arr(), collation)); Lock::DBLock dbLock(operationContext(), "db", MODE_IS); - auto resolvedView = getViewCatalog()->resolveView(operationContext(), view2); + auto resolvedView = getViewCatalog()->resolveView(operationContext(), view2, boost::none); ASSERT(resolvedView.isOK()); ASSERT_EQ(resolvedView.getValue().getNamespace(), viewOn); |