summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorDavid Percy <david.percy@mongodb.com>2023-01-23 18:32:43 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-02-04 00:28:43 +0000
commit2110371e64514ce3ddae01c08f5b225ba5eaadc5 (patch)
tree5ac4722497ae476869eb4b20fe9f51f38796f3e9 /src/mongo
parent6b7b85d787f099d1c0ce0a4199a1c3cc61c21647 (diff)
downloadmongo-2110371e64514ce3ddae01c08f5b225ba5eaadc5.tar.gz
SERVER-73110 Each shard should check extended-range for timeseries sorting
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/catalog/virtual_collection_impl.h3
-rw-r--r--src/mongo/db/commands/run_aggregate.cpp7
-rw-r--r--src/mongo/db/pipeline/document_source_internal_unpack_bucket.cpp13
-rw-r--r--src/mongo/db/pipeline/expression_context.h11
-rw-r--r--src/mongo/db/query/multiple_collection_accessor.h11
-rw-r--r--src/mongo/db/sorter/sorter.cpp3
6 files changed, 46 insertions, 2 deletions
diff --git a/src/mongo/db/catalog/virtual_collection_impl.h b/src/mongo/db/catalog/virtual_collection_impl.h
index 055c61283a2..4366d86ccd5 100644
--- a/src/mongo/db/catalog/virtual_collection_impl.h
+++ b/src/mongo/db/catalog/virtual_collection_impl.h
@@ -242,7 +242,8 @@ public:
}
bool getRequiresTimeseriesExtendedRangeSupport() const final {
- unimplementedTasserted();
+ // A virtual collection is never a time-series collection, so it never requires
+ // extended-range support.
return false;
}
diff --git a/src/mongo/db/commands/run_aggregate.cpp b/src/mongo/db/commands/run_aggregate.cpp
index 8db9c787f7f..8868ce91a8b 100644
--- a/src/mongo/db/commands/run_aggregate.cpp
+++ b/src/mongo/db/commands/run_aggregate.cpp
@@ -974,6 +974,13 @@ Status runAggregate(OperationContext* opCtx,
? collections.getMainCollection()->getCollectionOptions()
: boost::optional<CollectionOptions>(boost::none));
+ // If any involved collection contains extended-range data, set a flag which individual
+ // DocumentSource parsers can check.
+ collections.forEach([&](const CollectionPtr& coll) {
+ if (coll->getRequiresTimeseriesExtendedRangeSupport())
+ expCtx->setRequiresTimeseriesExtendedRangeSupport(true);
+ });
+
expCtx->startExpressionCounters();
auto pipeline = Pipeline::parse(request.getPipeline(), expCtx);
curOp->beginQueryPlanningTimer();
diff --git a/src/mongo/db/pipeline/document_source_internal_unpack_bucket.cpp b/src/mongo/db/pipeline/document_source_internal_unpack_bucket.cpp
index bc4d86b2744..256804b978f 100644
--- a/src/mongo/db/pipeline/document_source_internal_unpack_bucket.cpp
+++ b/src/mongo/db/pipeline/document_source_internal_unpack_bucket.cpp
@@ -291,6 +291,11 @@ boost::intrusive_ptr<DocumentSource> DocumentSourceInternalUnpackBucket::createF
// If neither "include" nor "exclude" is specified, the default is "exclude": [] and
// if that's the case, no field will be added to 'bucketSpec.fieldSet' in the for-loop below.
BucketSpec bucketSpec;
+ // Use extended-range support if any individual collection requires it, even if 'specElem'
+ // doesn't mention this flag.
+ if (expCtx->getRequiresTimeseriesExtendedRangeSupport()) {
+ bucketSpec.setUsesExtendedRange(true);
+ }
auto hasIncludeExclude = false;
auto hasTimeField = false;
auto hasBucketMaxSpanSeconds = false;
@@ -504,6 +509,14 @@ void DocumentSourceInternalUnpackBucket::serializeToArray(
if (_assumeNoMixedSchemaData)
out.addField(kAssumeNoMixedSchemaData, Value(_assumeNoMixedSchemaData));
+ if (spec.usesExtendedRange()) {
+ // Include this flag so that 'explain' is more helpful.
+ // But this is not so useful for communicating from one process to another,
+ // because mongos and/or the primary shard don't know whether any other shard
+ // has extended-range data.
+ out.addField(kUsesExtendedRange, Value{true});
+ }
+
if (!spec.computedMetaProjFields().empty())
out.addField("computedMetaProjFields", Value{[&] {
std::vector<Value> compFields;
diff --git a/src/mongo/db/pipeline/expression_context.h b/src/mongo/db/pipeline/expression_context.h
index 3ec3554a336..a0f04003479 100644
--- a/src/mongo/db/pipeline/expression_context.h
+++ b/src/mongo/db/pipeline/expression_context.h
@@ -511,6 +511,15 @@ public:
_gotTemporarilyUnavailableException = v;
}
+ // Sets or clears a flag which tells DocumentSource parsers whether any involved Collection
+ // may contain extended-range dates.
+ void setRequiresTimeseriesExtendedRangeSupport(bool v) {
+ _requiresTimeseriesExtendedRangeSupport = v;
+ }
+ bool getRequiresTimeseriesExtendedRangeSupport() const {
+ return _requiresTimeseriesExtendedRangeSupport;
+ }
+
protected:
static const int kInterruptCheckPeriod = 128;
@@ -535,6 +544,8 @@ protected:
bool _isCappedDelete = false;
+ bool _requiresTimeseriesExtendedRangeSupport = false;
+
private:
boost::optional<ExpressionCounters> _expressionCounters = boost::none;
bool _gotTemporarilyUnavailableException = false;
diff --git a/src/mongo/db/query/multiple_collection_accessor.h b/src/mongo/db/query/multiple_collection_accessor.h
index bf8c0ad5fe9..04c766770bb 100644
--- a/src/mongo/db/query/multiple_collection_accessor.h
+++ b/src/mongo/db/query/multiple_collection_accessor.h
@@ -101,6 +101,17 @@ public:
_secondaryColls.clear();
}
+ void forEach(std::function<void(const CollectionPtr&)> func) const {
+ if (hasMainCollection()) {
+ func(getMainCollection());
+ }
+ for (const auto& [name, coll] : getSecondaryCollections()) {
+ if (coll) {
+ func(coll);
+ }
+ }
+ }
+
private:
const CollectionPtr* _mainColl{&CollectionPtr::null};
diff --git a/src/mongo/db/sorter/sorter.cpp b/src/mongo/db/sorter/sorter.cpp
index 411c85ffbdb..92680a15971 100644
--- a/src/mongo/db/sorter/sorter.cpp
+++ b/src/mongo/db/sorter/sorter.cpp
@@ -1468,7 +1468,8 @@ void BoundedSorter<Key, Value, Comparator, BoundMaker>::add(Key key, Value value
invariant(!_done);
// If a new value violates what we thought was our min bound, something has gone wrong.
uassert(6369910,
- "BoundedSorter input is too out-of-order.",
+ str::stream() << "BoundedSorter input is too out-of-order: with bound "
+ << _min->toString() << ", did not expect input " << key.toString(),
!_checkInput || !_min || compare(*_min, key) <= 0);
// Each new item can potentially give us a tighter bound (a higher min).