diff options
author | Nick Zolnierz <nicholas.zolnierz@mongodb.com> | 2019-04-01 14:00:46 -0400 |
---|---|---|
committer | Nick Zolnierz <nicholas.zolnierz@mongodb.com> | 2019-04-10 15:24:09 -0400 |
commit | 1b00abfda7592d701f632b9550f973c56cea818f (patch) | |
tree | 27cd9a486b20875a9efb812c0468d26f596d803f /src | |
parent | 26404c6d4f6f37d4306d83900a7d481068f342ea (diff) | |
download | mongo-1b00abfda7592d701f632b9550f973c56cea818f.tar.gz |
SERVER-39403 Implement visitor for DocumentSource as precursor work for
encryption in agg
Diffstat (limited to 'src')
41 files changed, 299 insertions, 0 deletions
diff --git a/src/mongo/db/pipeline/document_source.h b/src/mongo/db/pipeline/document_source.h index f3f67db8e0a..de0ef8b209d 100644 --- a/src/mongo/db/pipeline/document_source.h +++ b/src/mongo/db/pipeline/document_source.h @@ -47,6 +47,7 @@ #include "mongo/db/namespace_string.h" #include "mongo/db/pipeline/dependencies.h" #include "mongo/db/pipeline/document.h" +#include "mongo/db/pipeline/document_source_visitor.h" #include "mongo/db/pipeline/expression_context.h" #include "mongo/db/pipeline/field_path.h" #include "mongo/db/pipeline/lite_parsed_document_source.h" @@ -468,6 +469,12 @@ public: return false; } + /** + * This allows an arbitrary class to implement logic which gets dispatched to at runtime + * depending on the type of the DocumentSource. + */ + virtual void acceptVisitor(DocumentSourceVisitor* visitor) = 0; + protected: explicit DocumentSource(const boost::intrusive_ptr<ExpressionContext>& pExpCtx); diff --git a/src/mongo/db/pipeline/document_source_bucket_auto.h b/src/mongo/db/pipeline/document_source_bucket_auto.h index 961ad0f9865..0ccb3981a13 100644 --- a/src/mongo/db/pipeline/document_source_bucket_auto.h +++ b/src/mongo/db/pipeline/document_source_bucket_auto.h @@ -88,6 +88,10 @@ public: static boost::intrusive_ptr<DocumentSource> createFromBson( BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& pExpCtx); + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + protected: void doDispose() final; diff --git a/src/mongo/db/pipeline/document_source_change_stream.h b/src/mongo/db/pipeline/document_source_change_stream.h index 077ec7ff616..c6ddf3c67c3 100644 --- a/src/mongo/db/pipeline/document_source_change_stream.h +++ b/src/mongo/db/pipeline/document_source_change_stream.h @@ -230,6 +230,10 @@ public: Value serialize(boost::optional<ExplainOptions::Verbosity> explain) const final; + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: DocumentSourceOplogMatch(BSONObj filter, const boost::intrusive_ptr<ExpressionContext>& expCtx); }; diff --git a/src/mongo/db/pipeline/document_source_change_stream_close_cursor.h b/src/mongo/db/pipeline/document_source_change_stream_close_cursor.h index d21a2170157..b19f6861495 100644 --- a/src/mongo/db/pipeline/document_source_change_stream_close_cursor.h +++ b/src/mongo/db/pipeline/document_source_change_stream_close_cursor.h @@ -82,6 +82,10 @@ public: return MergingLogic{nullptr, this, change_stream_constants::kSortSpec}; } + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: /** * Use the create static method to create a DocumentSourceCloseCursor. diff --git a/src/mongo/db/pipeline/document_source_change_stream_transform.h b/src/mongo/db/pipeline/document_source_change_stream_transform.h index ca1003128fd..425995498aa 100644 --- a/src/mongo/db/pipeline/document_source_change_stream_transform.h +++ b/src/mongo/db/pipeline/document_source_change_stream_transform.h @@ -63,6 +63,10 @@ public: return DocumentSourceChangeStream::kStageName.rawData(); } + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: // This constructor is private, callers should use the 'create()' method above. DocumentSourceChangeStreamTransform(const boost::intrusive_ptr<ExpressionContext>&, diff --git a/src/mongo/db/pipeline/document_source_check_invalidate.h b/src/mongo/db/pipeline/document_source_check_invalidate.h index 5e5b14f69af..2870bccc7f5 100644 --- a/src/mongo/db/pipeline/document_source_check_invalidate.h +++ b/src/mongo/db/pipeline/document_source_check_invalidate.h @@ -72,6 +72,10 @@ public: return new DocumentSourceCheckInvalidate(expCtx, ignoreFirstInvalidate); } + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: /** * Use the create static method to create a DocumentSourceCheckInvalidate. diff --git a/src/mongo/db/pipeline/document_source_check_resume_token.h b/src/mongo/db/pipeline/document_source_check_resume_token.h index c91c9813157..0a6d4b5e724 100644 --- a/src/mongo/db/pipeline/document_source_check_resume_token.h +++ b/src/mongo/db/pipeline/document_source_check_resume_token.h @@ -84,6 +84,10 @@ public: static boost::intrusive_ptr<DocumentSourceShardCheckResumability> create( const boost::intrusive_ptr<ExpressionContext>& expCtx, ResumeTokenData token); + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: /** * Use the create static method to create a DocumentSourceShardCheckResumability. @@ -145,6 +149,10 @@ public: static boost::intrusive_ptr<DocumentSourceEnsureResumeTokenPresent> create( const boost::intrusive_ptr<ExpressionContext>& expCtx, ResumeTokenData token); + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: /** * Use the create static method to create a DocumentSourceEnsureResumeTokenPresent. diff --git a/src/mongo/db/pipeline/document_source_coll_stats.h b/src/mongo/db/pipeline/document_source_coll_stats.h index 8cea821a23a..b9d4d8e8f3d 100644 --- a/src/mongo/db/pipeline/document_source_coll_stats.h +++ b/src/mongo/db/pipeline/document_source_coll_stats.h @@ -96,6 +96,10 @@ public: static boost::intrusive_ptr<DocumentSource> createFromBson( BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& pExpCtx); + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: // The raw object given to $collStats containing user specified options. BSONObj _collStatsSpec; diff --git a/src/mongo/db/pipeline/document_source_current_op.h b/src/mongo/db/pipeline/document_source_current_op.h index 84340c63e71..68f8493e290 100644 --- a/src/mongo/db/pipeline/document_source_current_op.h +++ b/src/mongo/db/pipeline/document_source_current_op.h @@ -133,6 +133,10 @@ public: Value serialize(boost::optional<ExplainOptions::Verbosity> explain = boost::none) const final; + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: DocumentSourceCurrentOp(const boost::intrusive_ptr<ExpressionContext>& pExpCtx, ConnMode includeIdleConnections, diff --git a/src/mongo/db/pipeline/document_source_cursor.h b/src/mongo/db/pipeline/document_source_cursor.h index d1ca145b886..94e34fed1f5 100644 --- a/src/mongo/db/pipeline/document_source_cursor.h +++ b/src/mongo/db/pipeline/document_source_cursor.h @@ -151,6 +151,10 @@ public: return _planSummaryStats; } + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + protected: DocumentSourceCursor(Collection* collection, std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> exec, diff --git a/src/mongo/db/pipeline/document_source_exchange.h b/src/mongo/db/pipeline/document_source_exchange.h index 4b6b821be82..1c4624f78a4 100644 --- a/src/mongo/db/pipeline/document_source_exchange.h +++ b/src/mongo/db/pipeline/document_source_exchange.h @@ -247,6 +247,10 @@ public: return _consumerId; } + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: boost::intrusive_ptr<Exchange> _exchange; diff --git a/src/mongo/db/pipeline/document_source_facet.h b/src/mongo/db/pipeline/document_source_facet.h index 74281663fb6..8dfe289e37d 100644 --- a/src/mongo/db/pipeline/document_source_facet.h +++ b/src/mongo/db/pipeline/document_source_facet.h @@ -145,6 +145,10 @@ public: StageConstraints constraints(Pipeline::SplitState pipeState) const final; bool usedDisk() final; + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + protected: void doDispose() final; diff --git a/src/mongo/db/pipeline/document_source_geo_near.h b/src/mongo/db/pipeline/document_source_geo_near.h index 749d9fee7cd..c9b50d6f586 100644 --- a/src/mongo/db/pipeline/document_source_geo_near.h +++ b/src/mongo/db/pipeline/document_source_geo_near.h @@ -125,6 +125,9 @@ public: */ boost::optional<MergingLogic> mergingLogic() final; + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } private: explicit DocumentSourceGeoNear(const boost::intrusive_ptr<ExpressionContext>& pExpCtx); diff --git a/src/mongo/db/pipeline/document_source_graph_lookup.h b/src/mongo/db/pipeline/document_source_graph_lookup.h index 6449560875b..2df71c08e72 100644 --- a/src/mongo/db/pipeline/document_source_graph_lookup.h +++ b/src/mongo/db/pipeline/document_source_graph_lookup.h @@ -105,6 +105,10 @@ public: static boost::intrusive_ptr<DocumentSource> createFromBson( BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& pExpCtx); + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + protected: void doDispose() final; diff --git a/src/mongo/db/pipeline/document_source_group.h b/src/mongo/db/pipeline/document_source_group.h index b166d8e8335..f65754ab7f5 100644 --- a/src/mongo/db/pipeline/document_source_group.h +++ b/src/mongo/db/pipeline/document_source_group.h @@ -172,6 +172,10 @@ public: std::unique_ptr<GroupFromFirstDocumentTransformation> rewriteGroupAsTransformOnFirstDocument() const; + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + protected: void doDispose() final; diff --git a/src/mongo/db/pipeline/document_source_index_stats.h b/src/mongo/db/pipeline/document_source_index_stats.h index 9b162ca4575..e4a3b30292e 100644 --- a/src/mongo/db/pipeline/document_source_index_stats.h +++ b/src/mongo/db/pipeline/document_source_index_stats.h @@ -89,6 +89,10 @@ public: static boost::intrusive_ptr<DocumentSource> createFromBson( BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& pExpCtx); + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: DocumentSourceIndexStats(const boost::intrusive_ptr<ExpressionContext>& pExpCtx); diff --git a/src/mongo/db/pipeline/document_source_internal_inhibit_optimization.h b/src/mongo/db/pipeline/document_source_internal_inhibit_optimization.h index 209c39308b8..ce99d887aed 100644 --- a/src/mongo/db/pipeline/document_source_internal_inhibit_optimization.h +++ b/src/mongo/db/pipeline/document_source_internal_inhibit_optimization.h @@ -68,6 +68,10 @@ public: GetNextResult getNext() final; + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: Value serialize(boost::optional<ExplainOptions::Verbosity> explain = boost::none) const final; }; diff --git a/src/mongo/db/pipeline/document_source_internal_split_pipeline.h b/src/mongo/db/pipeline/document_source_internal_split_pipeline.h index b2b30952dd2..9ed1ff52741 100644 --- a/src/mongo/db/pipeline/document_source_internal_split_pipeline.h +++ b/src/mongo/db/pipeline/document_source_internal_split_pipeline.h @@ -74,6 +74,10 @@ public: GetNextResult getNext() final; + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: DocumentSourceInternalSplitPipeline(const boost::intrusive_ptr<ExpressionContext>& expCtx, HostTypeRequirement mergeType) diff --git a/src/mongo/db/pipeline/document_source_limit.h b/src/mongo/db/pipeline/document_source_limit.h index 0a5ed1428a5..e6e5ce4c301 100644 --- a/src/mongo/db/pipeline/document_source_limit.h +++ b/src/mongo/db/pipeline/document_source_limit.h @@ -92,6 +92,10 @@ public: _limit = newLimit; } + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: DocumentSourceLimit(const boost::intrusive_ptr<ExpressionContext>& pExpCtx, long long limit); diff --git a/src/mongo/db/pipeline/document_source_list_cached_and_active_users.h b/src/mongo/db/pipeline/document_source_list_cached_and_active_users.h index 45df30ac5d8..6cbd2115973 100644 --- a/src/mongo/db/pipeline/document_source_list_cached_and_active_users.h +++ b/src/mongo/db/pipeline/document_source_list_cached_and_active_users.h @@ -109,6 +109,10 @@ public: static boost::intrusive_ptr<DocumentSource> createFromBson( BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& pExpCtx); + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: DocumentSourceListCachedAndActiveUsers(const boost::intrusive_ptr<ExpressionContext>& pExpCtx); diff --git a/src/mongo/db/pipeline/document_source_list_local_sessions.h b/src/mongo/db/pipeline/document_source_list_local_sessions.h index 57fcdf97a1e..0eeab06035c 100644 --- a/src/mongo/db/pipeline/document_source_list_local_sessions.h +++ b/src/mongo/db/pipeline/document_source_list_local_sessions.h @@ -123,6 +123,10 @@ public: static boost::intrusive_ptr<DocumentSource> createFromBson( BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& pExpCtx); + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: DocumentSourceListLocalSessions(const boost::intrusive_ptr<ExpressionContext>& pExpCtx, const ListSessionsSpec& spec); diff --git a/src/mongo/db/pipeline/document_source_list_sessions.h b/src/mongo/db/pipeline/document_source_list_sessions.h index 42bfe4faf71..15238c1df92 100644 --- a/src/mongo/db/pipeline/document_source_list_sessions.h +++ b/src/mongo/db/pipeline/document_source_list_sessions.h @@ -96,6 +96,10 @@ public: static boost::intrusive_ptr<DocumentSource> createFromBson( BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& pExpCtx); + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: DocumentSourceListSessions(const BSONObj& query, const boost::intrusive_ptr<ExpressionContext>& pExpCtx, diff --git a/src/mongo/db/pipeline/document_source_lookup.h b/src/mongo/db/pipeline/document_source_lookup.h index 1718ad5dc63..7f9bdd715cd 100644 --- a/src/mongo/db/pipeline/document_source_lookup.h +++ b/src/mongo/db/pipeline/document_source_lookup.h @@ -193,6 +193,10 @@ public: return buildPipeline(inputDoc); } + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + protected: void doDispose() final; diff --git a/src/mongo/db/pipeline/document_source_lookup_change_post_image.h b/src/mongo/db/pipeline/document_source_lookup_change_post_image.h index 504ad359625..3814f2245b9 100644 --- a/src/mongo/db/pipeline/document_source_lookup_change_post_image.h +++ b/src/mongo/db/pipeline/document_source_lookup_change_post_image.h @@ -108,6 +108,10 @@ public: return kStageName.rawData(); } + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: DocumentSourceLookupChangePostImage(const boost::intrusive_ptr<ExpressionContext>& expCtx) : DocumentSource(expCtx) {} diff --git a/src/mongo/db/pipeline/document_source_match.h b/src/mongo/db/pipeline/document_source_match.h index 1552c5b1219..a11c846e786 100644 --- a/src/mongo/db/pipeline/document_source_match.h +++ b/src/mongo/db/pipeline/document_source_match.h @@ -162,6 +162,10 @@ public: return boost::none; } + void acceptVisitor(DocumentSourceVisitor* visitor) { + visitor->visit(this); + } + protected: DocumentSourceMatch(const BSONObj& query, const boost::intrusive_ptr<ExpressionContext>& expCtx); diff --git a/src/mongo/db/pipeline/document_source_mock.h b/src/mongo/db/pipeline/document_source_mock.h index 3fb65ba7c13..ea1416cffcf 100644 --- a/src/mongo/db/pipeline/document_source_mock.h +++ b/src/mongo/db/pipeline/document_source_mock.h @@ -97,6 +97,10 @@ public: return boost::none; } + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + // Return documents from front of queue. std::deque<GetNextResult> queue; diff --git a/src/mongo/db/pipeline/document_source_out.h b/src/mongo/db/pipeline/document_source_out.h index 8f313213983..fee56a03dbb 100644 --- a/src/mongo/db/pipeline/document_source_out.h +++ b/src/mongo/db/pipeline/document_source_out.h @@ -249,6 +249,10 @@ public: static boost::intrusive_ptr<DocumentSource> createFromBson( BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& pExpCtx); + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + protected: // Stash the writeConcern of the original command as the operation context may change by the // time we start to spill $out writes. This is because certain aggregations (e.g. $exchange) diff --git a/src/mongo/db/pipeline/document_source_plan_cache_stats.h b/src/mongo/db/pipeline/document_source_plan_cache_stats.h index 9f5aed005b8..102496e334f 100644 --- a/src/mongo/db/pipeline/document_source_plan_cache_stats.h +++ b/src/mongo/db/pipeline/document_source_plan_cache_stats.h @@ -123,6 +123,10 @@ public: std::vector<Value>& array, boost::optional<ExplainOptions::Verbosity> explain = boost::none) const override; + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: DocumentSourcePlanCacheStats(const boost::intrusive_ptr<ExpressionContext>& expCtx); diff --git a/src/mongo/db/pipeline/document_source_redact.h b/src/mongo/db/pipeline/document_source_redact.h index a05f9d2e4ff..4babb90f0a6 100644 --- a/src/mongo/db/pipeline/document_source_redact.h +++ b/src/mongo/db/pipeline/document_source_redact.h @@ -66,6 +66,10 @@ public: Value serialize(boost::optional<ExplainOptions::Verbosity> explain = boost::none) const final; + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: DocumentSourceRedact(const boost::intrusive_ptr<ExpressionContext>& expCtx, const boost::intrusive_ptr<Expression>& previsit); diff --git a/src/mongo/db/pipeline/document_source_sample.h b/src/mongo/db/pipeline/document_source_sample.h index 3a5c7231d50..aa7c1e8aee1 100644 --- a/src/mongo/db/pipeline/document_source_sample.h +++ b/src/mongo/db/pipeline/document_source_sample.h @@ -66,6 +66,10 @@ public: static boost::intrusive_ptr<DocumentSource> createFromBson( BSONElement elem, const boost::intrusive_ptr<ExpressionContext>& expCtx); + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: explicit DocumentSourceSample(const boost::intrusive_ptr<ExpressionContext>& pExpCtx); diff --git a/src/mongo/db/pipeline/document_source_sample_from_random_cursor.h b/src/mongo/db/pipeline/document_source_sample_from_random_cursor.h index 8c9a6e99733..0f607657331 100644 --- a/src/mongo/db/pipeline/document_source_sample_from_random_cursor.h +++ b/src/mongo/db/pipeline/document_source_sample_from_random_cursor.h @@ -64,6 +64,10 @@ public: std::string idField, long long collectionSize); + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: DocumentSourceSampleFromRandomCursor(const boost::intrusive_ptr<ExpressionContext>& expCtx, long long size, diff --git a/src/mongo/db/pipeline/document_source_sequential_document_cache.h b/src/mongo/db/pipeline/document_source_sequential_document_cache.h index fa7d9133a2b..6d529254766 100644 --- a/src/mongo/db/pipeline/document_source_sequential_document_cache.h +++ b/src/mongo/db/pipeline/document_source_sequential_document_cache.h @@ -83,6 +83,10 @@ public: _cache->abandon(); } + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + protected: Pipeline::SourceContainer::iterator doOptimizeAt(Pipeline::SourceContainer::iterator itr, Pipeline::SourceContainer* container) final; diff --git a/src/mongo/db/pipeline/document_source_single_document_transformation.h b/src/mongo/db/pipeline/document_source_single_document_transformation.h index d9ca3a8e57b..41003ef2141 100644 --- a/src/mongo/db/pipeline/document_source_single_document_transformation.h +++ b/src/mongo/db/pipeline/document_source_single_document_transformation.h @@ -83,6 +83,10 @@ public: return _parsedTransform->isSubsetOfProjection(proj); } + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + protected: void doDispose() final; diff --git a/src/mongo/db/pipeline/document_source_skip.h b/src/mongo/db/pipeline/document_source_skip.h index d6bc4c88458..70ccb99b859 100644 --- a/src/mongo/db/pipeline/document_source_skip.h +++ b/src/mongo/db/pipeline/document_source_skip.h @@ -96,6 +96,10 @@ public: _nToSkip = newSkip; } + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: explicit DocumentSourceSkip(const boost::intrusive_ptr<ExpressionContext>& pExpCtx, long long nToSkip); diff --git a/src/mongo/db/pipeline/document_source_sort.h b/src/mongo/db/pipeline/document_source_sort.h index eeca2371b6e..cdb0bcadb99 100644 --- a/src/mongo/db/pipeline/document_source_sort.h +++ b/src/mongo/db/pipeline/document_source_sort.h @@ -140,6 +140,10 @@ public: return _limitSrc; } + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + protected: /** * Attempts to absorb a subsequent $limit stage so that it an perform a top-k sort. diff --git a/src/mongo/db/pipeline/document_source_tee_consumer.h b/src/mongo/db/pipeline/document_source_tee_consumer.h index 3c5ae5fc729..0279c001a76 100644 --- a/src/mongo/db/pipeline/document_source_tee_consumer.h +++ b/src/mongo/db/pipeline/document_source_tee_consumer.h @@ -78,6 +78,10 @@ public: Value serialize(boost::optional<ExplainOptions::Verbosity> explain = boost::none) const final; + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + protected: void doDispose() final; diff --git a/src/mongo/db/pipeline/document_source_test_optimizations.h b/src/mongo/db/pipeline/document_source_test_optimizations.h index 6bda5052d81..1c0bb51d25b 100644 --- a/src/mongo/db/pipeline/document_source_test_optimizations.h +++ b/src/mongo/db/pipeline/document_source_test_optimizations.h @@ -63,6 +63,10 @@ public: MONGO_UNREACHABLE; } + virtual void acceptVisitor(DocumentSourceVisitor* visitor) override { + visitor->visit(this); + } + private: virtual Value serialize(boost::optional<ExplainOptions::Verbosity>) const override { MONGO_UNREACHABLE; diff --git a/src/mongo/db/pipeline/document_source_unwind.h b/src/mongo/db/pipeline/document_source_unwind.h index 7948f6fdcd6..3904cc602de 100644 --- a/src/mongo/db/pipeline/document_source_unwind.h +++ b/src/mongo/db/pipeline/document_source_unwind.h @@ -90,6 +90,10 @@ public: return _indexPath; } + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: DocumentSourceUnwind(const boost::intrusive_ptr<ExpressionContext>& pExpCtx, const FieldPath& fieldPath, diff --git a/src/mongo/db/pipeline/document_source_visitor.h b/src/mongo/db/pipeline/document_source_visitor.h new file mode 100644 index 00000000000..58a8d3aebf6 --- /dev/null +++ b/src/mongo/db/pipeline/document_source_visitor.h @@ -0,0 +1,133 @@ +/** + * Copyright (C) 2019-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +namespace mongo { + +class DocumentSourceMergeCursors; +class DocumentSourceSequentialDocumentCache; +class DocumentSourceSample; +class DocumentSourceUnwind; +class DocumentSourceCloseCursor; +class DocumentSourceGeoNear; +class DocumentSourceLookUp; +class DocumentSourceInternalInhibitOptimization; +class DocumentSourceLookupChangePostImage; +class DocumentSourceListCachedAndActiveUsers; +class DocumentSourceChangeStreamTransform; +class DocumentSourceOut; +class DocumentSourceRedact; +class DocumentSourceGraphLookUp; +class DocumentSourceExchange; +class DocumentSourceCursor; +class DocumentSourceBucketAuto; +class DocumentSourceSkip; +class DocumentSourceSort; +class DocumentSourceGroup; +class DocumentSourceMock; +class DocumentSourceListLocalSessions; +class DocumentSourcePlanCacheStats; +class DocumentSourceIndexStats; +class DocumentSourceLimit; +class DocumentSourceCurrentOp; +class DocumentSourceSingleDocumentTransformation; +class DocumentSourceChangeStream; +class DocumentSourceShardCheckResumability; +class DocumentSourceEnsureResumeTokenPresent; +class DocumentSourceCheckInvalidate; +class DocumentSourceFacet; +class DocumentSourceInternalSplitPipeline; +class DocumentSourceListSessions; +class DocumentSourceCollStats; +class DocumentSourceTeeConsumer; +class DocumentSourceSampleFromRandomCursor; +class DocumentSourceMatch; +class DocumentSourceOplogMatch; +class DocumentSourceUpdateOnAddShard; +class DocumentSourceBackupCursorExtend; +class DocumentSourceBackupCursor; +class DocumentSourceTestOptimizations; + +/** + * This is a base class to allow for dynamic dispatch on a DocumentSource. It implements the visitor + * pattern, in which every derived class from DocumentSource implements an acceptVisitor() method, + * which simply calls the appropriate visit() method on the derived DocumentSourceVisitor class. The + * derived class can do whatever it needs to do for each specific node type in the corresponding + * visit() method. + */ +class DocumentSourceVisitor { +public: + virtual ~DocumentSourceVisitor() = default; + + virtual void visit(DocumentSourceMergeCursors* source) = 0; + virtual void visit(DocumentSourceSequentialDocumentCache* source) = 0; + virtual void visit(DocumentSourceSample* source) = 0; + virtual void visit(DocumentSourceUnwind* source) = 0; + virtual void visit(DocumentSourceCloseCursor* source) = 0; + virtual void visit(DocumentSourceGeoNear* source) = 0; + virtual void visit(DocumentSourceLookUp* source) = 0; + virtual void visit(DocumentSourceInternalInhibitOptimization* source) = 0; + virtual void visit(DocumentSourceLookupChangePostImage* source) = 0; + virtual void visit(DocumentSourceListCachedAndActiveUsers* source) = 0; + virtual void visit(DocumentSourceChangeStreamTransform* source) = 0; + virtual void visit(DocumentSourceOut* source) = 0; + virtual void visit(DocumentSourceRedact* source) = 0; + virtual void visit(DocumentSourceGraphLookUp* source) = 0; + virtual void visit(DocumentSourceExchange* source) = 0; + virtual void visit(DocumentSourceCursor* source) = 0; + virtual void visit(DocumentSourceBucketAuto* source) = 0; + virtual void visit(DocumentSourceSkip* source) = 0; + virtual void visit(DocumentSourceSort* source) = 0; + virtual void visit(DocumentSourceGroup* source) = 0; + virtual void visit(DocumentSourceMock* source) = 0; + virtual void visit(DocumentSourceListLocalSessions* source) = 0; + virtual void visit(DocumentSourcePlanCacheStats* source) = 0; + virtual void visit(DocumentSourceIndexStats* source) = 0; + virtual void visit(DocumentSourceLimit* source) = 0; + virtual void visit(DocumentSourceCurrentOp* source) = 0; + virtual void visit(DocumentSourceSingleDocumentTransformation* source) = 0; + virtual void visit(DocumentSourceOplogMatch* source) = 0; + virtual void visit(DocumentSourceShardCheckResumability* source) = 0; + virtual void visit(DocumentSourceEnsureResumeTokenPresent* source) = 0; + virtual void visit(DocumentSourceCheckInvalidate* source) = 0; + virtual void visit(DocumentSourceFacet* source) = 0; + virtual void visit(DocumentSourceInternalSplitPipeline* source) = 0; + virtual void visit(DocumentSourceListSessions* source) = 0; + virtual void visit(DocumentSourceCollStats* source) = 0; + virtual void visit(DocumentSourceTeeConsumer* source) = 0; + virtual void visit(DocumentSourceSampleFromRandomCursor* source) = 0; + virtual void visit(DocumentSourceMatch* source) = 0; + virtual void visit(DocumentSourceUpdateOnAddShard* source) = 0; + virtual void visit(DocumentSourceBackupCursorExtend* source) = 0; + virtual void visit(DocumentSourceBackupCursor* source) = 0; + virtual void visit(DocumentSourceTestOptimizations* source) = 0; +}; + +} // namespace mongo diff --git a/src/mongo/s/query/document_source_merge_cursors.h b/src/mongo/s/query/document_source_merge_cursors.h index d3273b08123..29667a45019 100644 --- a/src/mongo/s/query/document_source_merge_cursors.h +++ b/src/mongo/s/query/document_source_merge_cursors.h @@ -144,6 +144,10 @@ public: _ownCursors = false; } + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + protected: void doDispose() final; diff --git a/src/mongo/s/query/document_source_update_on_add_shard.h b/src/mongo/s/query/document_source_update_on_add_shard.h index 2f77bb0d602..9da7e308928 100644 --- a/src/mongo/s/query/document_source_update_on_add_shard.h +++ b/src/mongo/s/query/document_source_update_on_add_shard.h @@ -78,6 +78,10 @@ public: GetNextResult getNext() final; + void acceptVisitor(DocumentSourceVisitor* visitor) final { + visitor->visit(this); + } + private: DocumentSourceUpdateOnAddShard(const boost::intrusive_ptr<ExpressionContext>&, executor::TaskExecutor*, |