diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/commands/run_aggregate.cpp | 7 | ||||
-rw-r--r-- | src/mongo/db/pipeline/document_source_internal_unpack_bucket.cpp | 13 | ||||
-rw-r--r-- | src/mongo/db/pipeline/expression_context.h | 11 | ||||
-rw-r--r-- | src/mongo/db/query/multiple_collection_accessor.h | 11 | ||||
-rw-r--r-- | src/mongo/db/sorter/sorter.cpp | 3 |
5 files changed, 44 insertions, 1 deletions
diff --git a/src/mongo/db/commands/run_aggregate.cpp b/src/mongo/db/commands/run_aggregate.cpp index 9172103b493..200dc47401f 100644 --- a/src/mongo/db/commands/run_aggregate.cpp +++ b/src/mongo/db/commands/run_aggregate.cpp @@ -914,6 +914,13 @@ Status runAggregate(OperationContext* opCtx, expCtx = makeExpressionContext( opCtx, request, std::move(*collatorToUse), uuid, collatorToUseMatchesDefault); + // 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); expCtx->stopExpressionCounters(); 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 49ec3811575..15831e48ae7 100644 --- a/src/mongo/db/pipeline/document_source_internal_unpack_bucket.cpp +++ b/src/mongo/db/pipeline/document_source_internal_unpack_bucket.cpp @@ -259,6 +259,11 @@ boost::intrusive_ptr<DocumentSource> DocumentSourceInternalUnpackBucket::createF // if that's the case, no field will be added to 'bucketSpec.fieldSet' in the for-loop below. BucketUnpacker::Behavior unpackerBehavior = BucketUnpacker::Behavior::kExclude; 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; @@ -456,6 +461,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 3139762d5cf..f159b240721 100644 --- a/src/mongo/db/pipeline/expression_context.h +++ b/src/mongo/db/pipeline/expression_context.h @@ -489,6 +489,15 @@ public: // expression counting. bool enabledCounters = true; + // 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; @@ -513,6 +522,8 @@ protected: bool _isCappedDelete = false; + bool _requiresTimeseriesExtendedRangeSupport = false; + private: boost::optional<ExpressionCounters> _expressionCounters = boost::none; }; diff --git a/src/mongo/db/query/multiple_collection_accessor.h b/src/mongo/db/query/multiple_collection_accessor.h index 26fc081000e..9d302ce2b28 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 a18297e493d..93ba45e4d74 100644 --- a/src/mongo/db/sorter/sorter.cpp +++ b/src/mongo/db/sorter/sorter.cpp @@ -1423,7 +1423,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). |