summaryrefslogtreecommitdiff
path: root/src/mongo/db/views
diff options
context:
space:
mode:
authorsamontea <merciers.merciers@gmail.com>2021-11-16 14:54:47 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-12-14 22:02:37 +0000
commit8fb1d8039361bcbf3a0ab77127cc6712783485ca (patch)
tree2681117e701eaffd05e48ea49f4f444044a320a5 /src/mongo/db/views
parent56d055c507a94a70e31a014142934060b76710ed (diff)
downloadmongo-8fb1d8039361bcbf3a0ab77127cc6712783485ca.tar.gz
SERVER-60672 Simpler pushdown when timeseries collection has no mixed-schema buckets
Diffstat (limited to 'src/mongo/db/views')
-rw-r--r--src/mongo/db/views/SConscript1
-rw-r--r--src/mongo/db/views/resolved_view.cpp32
-rw-r--r--src/mongo/db/views/resolved_view.h9
-rw-r--r--src/mongo/db/views/view_catalog.cpp18
4 files changed, 56 insertions, 4 deletions
diff --git a/src/mongo/db/views/SConscript b/src/mongo/db/views/SConscript
index 5ca16d561ed..38d2204fce9 100644
--- a/src/mongo/db/views/SConscript
+++ b/src/mongo/db/views/SConscript
@@ -27,6 +27,7 @@ env.Library(
],
LIBDEPS=[
'$BUILD_DIR/mongo/base',
+ '$BUILD_DIR/mongo/db/catalog/collection',
'$BUILD_DIR/mongo/db/pipeline/aggregation',
'$BUILD_DIR/mongo/db/query/collation/collator_factory_interface',
'$BUILD_DIR/mongo/db/repl/repl_coordinator_interface',
diff --git a/src/mongo/db/views/resolved_view.cpp b/src/mongo/db/views/resolved_view.cpp
index 9c754c559e7..c0435b8e924 100644
--- a/src/mongo/db/views/resolved_view.cpp
+++ b/src/mongo/db/views/resolved_view.cpp
@@ -72,15 +72,30 @@ ResolvedView ResolvedView::fromBSON(const BSONObj& commandResponseObj) {
collationSpec = collationElt.embeddedObject().getOwned();
}
+
+ boost::optional<bool> mixedSchema = boost::none;
+ if (auto mixedSchemaElem = viewDef[kTimeseriesMayContainMixedData]) {
+ uassert(6067204,
+ str::stream() << "view definition must have " << kTimeseriesMayContainMixedData
+ << " of type bool or no such field",
+ mixedSchemaElem.type() == BSONType::Bool);
+
+ mixedSchema = boost::optional<bool>(mixedSchemaElem.boolean());
+ }
+
return {NamespaceString(viewDef["ns"].valueStringData()),
std::move(pipeline),
- std::move(collationSpec)};
+ std::move(collationSpec),
+ std::move(mixedSchema)};
}
void ResolvedView::serialize(BSONObjBuilder* builder) const {
BSONObjBuilder subObj(builder->subobjStart("resolvedView"));
subObj.append("ns", _namespace.ns());
subObj.append("pipeline", _pipeline);
+ // Only serialize if it doesn't contain mixed data.
+ if ((_timeseriesMayContainMixedData && !(*_timeseriesMayContainMixedData)))
+ subObj.append(kTimeseriesMayContainMixedData, *_timeseriesMayContainMixedData);
if (!_defaultCollation.isEmpty()) {
subObj.append("collation", _defaultCollation);
}
@@ -125,6 +140,21 @@ AggregateCommandRequest ResolvedView::asExpandedViewAggregation(
}
resolvedPipeline[1] =
BSON(DocumentSourceInternalConvertBucketIndexStats::kStageName << builder.obj());
+ } else if (resolvedPipeline.size() >= 1 &&
+ resolvedPipeline[0][DocumentSourceInternalUnpackBucket::kStageNameInternal] &&
+ serverGlobalParams.featureCompatibility.isGreaterThanOrEqualTo(
+ multiversion::FeatureCompatibilityVersion::kVersion_5_2)) {
+ auto unpackStage = resolvedPipeline[0];
+
+ BSONObjBuilder builder;
+ for (const auto& elem :
+ unpackStage[DocumentSourceInternalUnpackBucket::kStageNameInternal].Obj()) {
+ builder.append(elem);
+ }
+ builder.append(DocumentSourceInternalUnpackBucket::kAssumeNoMixedSchemaData,
+ ((_timeseriesMayContainMixedData && !(*_timeseriesMayContainMixedData))));
+ resolvedPipeline[0] =
+ BSON(DocumentSourceInternalUnpackBucket::kStageNameInternal << builder.obj());
}
AggregateCommandRequest expandedRequest{_namespace, resolvedPipeline};
diff --git a/src/mongo/db/views/resolved_view.h b/src/mongo/db/views/resolved_view.h
index 19cfefe82f9..d19642c8dd5 100644
--- a/src/mongo/db/views/resolved_view.h
+++ b/src/mongo/db/views/resolved_view.h
@@ -46,10 +46,12 @@ class ResolvedView final : public ErrorExtraInfo {
public:
ResolvedView(const NamespaceString& collectionNs,
std::vector<BSONObj> pipeline,
- BSONObj defaultCollation)
+ BSONObj defaultCollation,
+ boost::optional<bool> timeseriesMayContainMixedData = boost::none)
: _namespace(collectionNs),
_pipeline(std::move(pipeline)),
- _defaultCollation(std::move(defaultCollation)) {}
+ _defaultCollation(std::move(defaultCollation)),
+ _timeseriesMayContainMixedData(timeseriesMayContainMixedData) {}
static ResolvedView fromBSON(const BSONObj& commandResponseObj);
@@ -74,6 +76,7 @@ public:
// ErrorExtraInfo API
static constexpr auto code = ErrorCodes::CommandOnShardedViewNotSupportedOnMongod;
+ static constexpr StringData kTimeseriesMayContainMixedData = "timeseriesMayContainMixedData"_sd;
void serialize(BSONObjBuilder* bob) const final;
static std::shared_ptr<const ErrorExtraInfo> parse(const BSONObj&);
@@ -88,6 +91,8 @@ private:
// that operations on the view which do not specify a collation inherit the default. Operations
// on the view which specify any other collation fail with a user error.
BSONObj _defaultCollation;
+
+ boost::optional<bool> _timeseriesMayContainMixedData;
};
} // namespace mongo
diff --git a/src/mongo/db/views/view_catalog.cpp b/src/mongo/db/views/view_catalog.cpp
index 84e0f7b46a8..b043eb5a03d 100644
--- a/src/mongo/db/views/view_catalog.cpp
+++ b/src/mongo/db/views/view_catalog.cpp
@@ -740,6 +740,7 @@ StatusWith<ResolvedView> ViewCatalog::resolveView(
std::vector<NamespaceString> dependencyChain{nss};
int depth = 0;
+ boost::optional<bool> mixedData = boost::none;
for (; depth < ViewGraph::kMaxViewDepth; depth++) {
auto view =
_lookup(opCtx, *resolvedNss, ViewCatalogLookupBehavior::kValidateDurableViews);
@@ -761,10 +762,25 @@ StatusWith<ResolvedView> ViewCatalog::resolveView(
return StatusWith<ResolvedView>(
{*resolvedNss,
std::move(resolvedPipeline),
- collation ? std::move(collation.get()) : CollationSpec::kSimpleSpec});
+ collation ? std::move(collation.get()) : CollationSpec::kSimpleSpec,
+ mixedData});
}
resolvedNss = &view->viewOn();
+
+ if (view->timeseries()) {
+ auto tsCollection =
+ CollectionCatalog::get(opCtx)->lookupCollectionByNamespace(opCtx, *resolvedNss);
+ tassert(6067201,
+ str::stream() << "expected time-series buckets collection " << *resolvedNss
+ << " to exist",
+
+ tsCollection);
+ mixedData = tsCollection
+ ? tsCollection->getTimeseriesBucketsMayHaveMixedSchemaData()
+ : false;
+ }
+
dependencyChain.push_back(*resolvedNss);
if (!collation) {
if (timeSeriesCollator) {