diff options
-rw-r--r-- | jstests/core/list_all_sessions.js | 7 | ||||
-rw-r--r-- | src/mongo/db/pipeline/document_source_list_sessions.cpp | 20 | ||||
-rw-r--r-- | src/mongo/db/pipeline/document_source_list_sessions.h | 12 | ||||
-rw-r--r-- | src/mongo/db/pipeline/document_source_list_sessions.idl | 4 | ||||
-rw-r--r-- | src/mongo/db/pipeline/document_source_match.h | 3 |
5 files changed, 37 insertions, 9 deletions
diff --git a/jstests/core/list_all_sessions.js b/jstests/core/list_all_sessions.js index dd44d96408a..57dcd1f2490 100644 --- a/jstests/core/list_all_sessions.js +++ b/jstests/core/list_all_sessions.js @@ -14,6 +14,10 @@ function listSessions() { return config.system.sessions.aggregate(pipeline); } + function listSessionsWithFilter(filter) { + return config.system.sessions.aggregate( + [{'$listSessions': {allUsers: true}}, {$match: filter}]); + } // Get current log level. let originalLogLevel = assert.commandWorked(admin.setLogLevel(1)).was.verbosity; @@ -40,6 +44,9 @@ return resultArrayMine.length == 1; }, "Failed to locate session in collection"); + const sessionList = listSessionsWithFilter({_id: "non_existent"}).toArray(); + assert.eq(0, sessionList.length, tojson(sessionList)); + // Make sure pipelining other collections fail. assertErrorCode(admin.system.collections, pipeline, ErrorCodes.InvalidNamespace); } finally { diff --git a/src/mongo/db/pipeline/document_source_list_sessions.cpp b/src/mongo/db/pipeline/document_source_list_sessions.cpp index 52da67b15a4..2d71e9a3cbf 100644 --- a/src/mongo/db/pipeline/document_source_list_sessions.cpp +++ b/src/mongo/db/pipeline/document_source_list_sessions.cpp @@ -55,9 +55,15 @@ boost::intrusive_ptr<DocumentSource> DocumentSourceListSessions::createFromBson( nss == NamespaceString::kLogicalSessionsNamespace); const auto& spec = listSessionsParseSpec(kStageName, elem); + if (const auto& pred = spec.getPredicate()) { + // Predicate has already been determined and might have changed during optimization, use it + // directly. + return new DocumentSourceListSessions(*pred, pExpCtx, spec.getAllUsers(), spec.getUsers()); + } if (spec.getAllUsers()) { // No filtration. optimize() should later skip us. - return new DocumentSourceListSessions(BSONObj(), pExpCtx, spec); + return new DocumentSourceListSessions( + BSONObj(), pExpCtx, spec.getAllUsers(), spec.getUsers()); } invariant(spec.getUsers() && !spec.getUsers()->empty()); @@ -67,7 +73,17 @@ boost::intrusive_ptr<DocumentSource> DocumentSourceListSessions::createFromBson( builder.append(BSONBinData(cdr.data(), cdr.length(), BinDataGeneral)); } const auto& query = BSON("_id.uid" << BSON("$in" << builder.arr())); - return new DocumentSourceListSessions(query, pExpCtx, spec); + return new DocumentSourceListSessions(query, pExpCtx, spec.getAllUsers(), spec.getUsers()); +} + + +Value DocumentSourceListSessions::serialize( + boost::optional<ExplainOptions::Verbosity> explain) const { + ListSessionsSpec spec; + spec.setAllUsers(_allUsers); + spec.setUsers(_users); + spec.setPredicate(_predicate); + return Value(Document{{getSourceName(), spec.toBSON()}}); } } // namespace mongo diff --git a/src/mongo/db/pipeline/document_source_list_sessions.h b/src/mongo/db/pipeline/document_source_list_sessions.h index 028460ccc7e..6d537fb3ab3 100644 --- a/src/mongo/db/pipeline/document_source_list_sessions.h +++ b/src/mongo/db/pipeline/document_source_list_sessions.h @@ -83,9 +83,7 @@ public: return kStageName; } - Value serialize(boost::optional<ExplainOptions::Verbosity> explain = boost::none) const final { - return Value(Document{{getSourceName(), _spec.toBSON()}}); - } + Value serialize(boost::optional<ExplainOptions::Verbosity> explain = boost::none) const final; StageConstraints constraints(Pipeline::SplitState pipeState) const final { return {StreamType::kStreaming, @@ -102,10 +100,12 @@ public: private: DocumentSourceListSessions(const BSONObj& query, const boost::intrusive_ptr<ExpressionContext>& pExpCtx, - const ListSessionsSpec& spec) - : DocumentSourceMatch(query, pExpCtx), _spec(spec) {} + const bool allUsers, + const boost::optional<std::vector<mongo::ListSessionsUser>>& users) + : DocumentSourceMatch(query, pExpCtx), _allUsers(allUsers), _users(users) {} - const ListSessionsSpec _spec; + bool _allUsers; + boost::optional<std::vector<mongo::ListSessionsUser>> _users; }; } // namespace mongo diff --git a/src/mongo/db/pipeline/document_source_list_sessions.idl b/src/mongo/db/pipeline/document_source_list_sessions.idl index e9bc344f74e..0db282831dc 100644 --- a/src/mongo/db/pipeline/document_source_list_sessions.idl +++ b/src/mongo/db/pipeline/document_source_list_sessions.idl @@ -53,3 +53,7 @@ structs: users: type: array<ListSessionsUser> optional: true + $_internalPredicate: + cpp_name: predicate + type: object + optional: true diff --git a/src/mongo/db/pipeline/document_source_match.h b/src/mongo/db/pipeline/document_source_match.h index 7be3676c629..fd08a52250c 100644 --- a/src/mongo/db/pipeline/document_source_match.h +++ b/src/mongo/db/pipeline/document_source_match.h @@ -166,10 +166,11 @@ protected: DocumentSourceMatch(const BSONObj& query, const boost::intrusive_ptr<ExpressionContext>& expCtx); + BSONObj _predicate; + private: std::unique_ptr<MatchExpression> _expression; - BSONObj _predicate; const bool _isTextQuery; // Cache the dependencies so that we know what fields we need to serialize to BSON for matching. |