diff options
author | Ben Shteinfeld <ben.shteinfeld@mongodb.com> | 2022-12-27 18:38:00 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2023-01-05 20:46:43 +0000 |
commit | 4350dacd31d3fe1adf51a07cf3d59406fa2351e3 (patch) | |
tree | 694928e49f4016e2838bc1f3bd1dbefa7a2cedee /src/mongo/db/pipeline/visitors | |
parent | af1ad78010f1396ad09f2f96e16705598f45a54b (diff) | |
download | mongo-4350dacd31d3fe1adf51a07cf3d59406fa2351e3.tar.gz |
SERVER-71943 Move ABT translation to new visitor mechanism
Diffstat (limited to 'src/mongo/db/pipeline/visitors')
4 files changed, 8 insertions, 278 deletions
diff --git a/src/mongo/db/pipeline/visitors/document_source_visitor.h b/src/mongo/db/pipeline/visitors/document_source_visitor.h deleted file mode 100644 index 13180f1f42d..00000000000 --- a/src/mongo/db/pipeline/visitors/document_source_visitor.h +++ /dev/null @@ -1,140 +0,0 @@ -/** - * Copyright (C) 2022-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 - -#include "mongo/db/query/tree_walker.h" - -namespace mongo { - -class DocumentSourceBucketAuto; -class DocumentSourceCollStats; -class DocumentSourceCurrentOp; -class DocumentSourceCursor; -class DocumentSourceExchange; -class DocumentSourceFacet; -class DocumentSourceGeoNear; -class DocumentSourceGeoNearCursor; -class DocumentSourceGraphLookUp; -class DocumentSourceGroup; -class DocumentSourceIndexStats; -class DocumentSourceInternalInhibitOptimization; -class DocumentSourceInternalShardFilter; -class DocumentSourceInternalSplitPipeline; -class DocumentSourceInternalUnpackBucket; -class DocumentSourceLimit; -class DocumentSourceListCachedAndActiveUsers; -class DocumentSourceListLocalSessions; -class DocumentSourceListSessions; -class DocumentSourceLookUp; -class DocumentSourceMatch; -class DocumentSourceMerge; -class DocumentSourceMergeCursors; -class DocumentSourceOperationMetrics; -class DocumentSourceOut; -class DocumentSourcePlanCacheStats; -class DocumentSourceQueue; -class DocumentSourceRedact; -class DocumentSourceSample; -class DocumentSourceSampleFromRandomCursor; -class DocumentSourceSequentialDocumentCache; -class DocumentSourceSingleDocumentTransformation; -class DocumentSourceSkip; -class DocumentSourceSort; -class DocumentSourceTeeConsumer; -class DocumentSourceTelemetry; -class DocumentSourceUnionWith; -class DocumentSourceUnwind; - -/** - * Visitor pattern for pipeline document sources. - * - * This code is not responsible for traversing the tree, only for performing the double-dispatch. - * - * If the visitor doesn't intend to modify the tree, then the template argument 'IsConst' should be - * set to 'true'. In this case all 'visit()' methods will take a const pointer to a visiting node. - */ -template <bool IsConst = false> -class DocumentSourceVisitor { -public: - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceBucketAuto> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceCollStats> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceCurrentOp> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceCursor> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceExchange> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceFacet> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceGeoNear> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceGeoNearCursor> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceGraphLookUp> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceGroup> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceIndexStats> source) = 0; - virtual void visit( - tree_walker::MaybeConstPtr<IsConst, DocumentSourceInternalInhibitOptimization> source) = 0; - virtual void visit( - tree_walker::MaybeConstPtr<IsConst, DocumentSourceInternalShardFilter> source) = 0; - virtual void visit( - tree_walker::MaybeConstPtr<IsConst, DocumentSourceInternalSplitPipeline> source) = 0; - virtual void visit( - tree_walker::MaybeConstPtr<IsConst, DocumentSourceInternalUnpackBucket> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceLimit> source) = 0; - virtual void visit( - tree_walker::MaybeConstPtr<IsConst, DocumentSourceListCachedAndActiveUsers> source) = 0; - virtual void visit( - tree_walker::MaybeConstPtr<IsConst, DocumentSourceListLocalSessions> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceListSessions> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceLookUp> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceMatch> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceMerge> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceMergeCursors> source) = 0; - virtual void visit( - tree_walker::MaybeConstPtr<IsConst, DocumentSourceOperationMetrics> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceOut> source) = 0; - virtual void visit( - tree_walker::MaybeConstPtr<IsConst, DocumentSourcePlanCacheStats> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceQueue> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceRedact> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceSample> source) = 0; - virtual void visit( - tree_walker::MaybeConstPtr<IsConst, DocumentSourceSampleFromRandomCursor> source) = 0; - virtual void visit( - tree_walker::MaybeConstPtr<IsConst, DocumentSourceSequentialDocumentCache> source) = 0; - virtual void visit( - tree_walker::MaybeConstPtr<IsConst, DocumentSourceSingleDocumentTransformation> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceSkip> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceSort> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceTeeConsumer> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceTelemetry> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceUnionWith> source) = 0; - virtual void visit(tree_walker::MaybeConstPtr<IsConst, DocumentSourceUnwind> source) = 0; -}; - -using DocumentSourceMutableVisitor = DocumentSourceVisitor<false>; -using DocumentSourceConstVisitor = DocumentSourceVisitor<true>; - -} // namespace mongo diff --git a/src/mongo/db/pipeline/visitors/document_source_visitor_registry_mongod.h b/src/mongo/db/pipeline/visitors/document_source_visitor_registry_mongod.h index b586feffa5f..3056584979e 100644 --- a/src/mongo/db/pipeline/visitors/document_source_visitor_registry_mongod.h +++ b/src/mongo/db/pipeline/visitors/document_source_visitor_registry_mongod.h @@ -109,6 +109,14 @@ template <typename T> void registerMongodVisitor(ServiceContext* service) { auto& registry = getDocumentSourceVisitorRegistry(service); registerVisitFuncs<T, + // These document sources are defined in the 'query_exec' library, so having + // them here causes a circular dependency. We should ideally factor them out + // into their own library (or as part of libpipeline) but this requires a + // large refactor of the 'query_exec' library. + // It should be safe to ignore these for now as the only user of the visitor + // is CQF, which won't encounter these DocumentSources. + // DocumentSourceCursor, + // DocumentSourceGeoNearCursor, DocumentSourceBucketAuto, DocumentSourceChangeStreamAddPostImage, DocumentSourceChangeStreamAddPreImage, @@ -120,12 +128,10 @@ void registerMongodVisitor(ServiceContext* service) { DocumentSourceChangeStreamUnwindTransaction, DocumentSourceCollStats, DocumentSourceCurrentOp, - DocumentSourceCursor, DocumentSourceExchange, DocumentSourceFacet, DocumentSourceFindAndModifyImageLookup, DocumentSourceGeoNear, - DocumentSourceGeoNearCursor, DocumentSourceGraphLookUp, DocumentSourceGroup, DocumentSourceIndexStats, diff --git a/src/mongo/db/pipeline/visitors/document_source_walker.cpp b/src/mongo/db/pipeline/visitors/document_source_walker.cpp index d10450649cc..6076aaf82e5 100644 --- a/src/mongo/db/pipeline/visitors/document_source_walker.cpp +++ b/src/mongo/db/pipeline/visitors/document_source_walker.cpp @@ -29,122 +29,8 @@ #include "mongo/db/pipeline/visitors/document_source_walker.h" -#include "mongo/base/error_codes.h" -#include "mongo/db/pipeline/document_source_bucket_auto.h" -#include "mongo/db/pipeline/document_source_coll_stats.h" -#include "mongo/db/pipeline/document_source_current_op.h" -#include "mongo/db/pipeline/document_source_cursor.h" -#include "mongo/db/pipeline/document_source_exchange.h" -#include "mongo/db/pipeline/document_source_facet.h" -#include "mongo/db/pipeline/document_source_geo_near.h" -#include "mongo/db/pipeline/document_source_geo_near_cursor.h" -#include "mongo/db/pipeline/document_source_graph_lookup.h" -#include "mongo/db/pipeline/document_source_group.h" -#include "mongo/db/pipeline/document_source_index_stats.h" -#include "mongo/db/pipeline/document_source_internal_inhibit_optimization.h" -#include "mongo/db/pipeline/document_source_internal_shard_filter.h" -#include "mongo/db/pipeline/document_source_internal_split_pipeline.h" -#include "mongo/db/pipeline/document_source_internal_unpack_bucket.h" -#include "mongo/db/pipeline/document_source_limit.h" -#include "mongo/db/pipeline/document_source_list_cached_and_active_users.h" -#include "mongo/db/pipeline/document_source_list_local_sessions.h" -#include "mongo/db/pipeline/document_source_list_sessions.h" -#include "mongo/db/pipeline/document_source_lookup.h" -#include "mongo/db/pipeline/document_source_match.h" -#include "mongo/db/pipeline/document_source_merge.h" -#include "mongo/db/pipeline/document_source_operation_metrics.h" -#include "mongo/db/pipeline/document_source_out.h" -#include "mongo/db/pipeline/document_source_plan_cache_stats.h" -#include "mongo/db/pipeline/document_source_queue.h" -#include "mongo/db/pipeline/document_source_redact.h" -#include "mongo/db/pipeline/document_source_sample.h" -#include "mongo/db/pipeline/document_source_sample_from_random_cursor.h" -#include "mongo/db/pipeline/document_source_sequential_document_cache.h" -#include "mongo/db/pipeline/document_source_single_document_transformation.h" -#include "mongo/db/pipeline/document_source_skip.h" -#include "mongo/db/pipeline/document_source_sort.h" -#include "mongo/db/pipeline/document_source_tee_consumer.h" -#include "mongo/db/pipeline/document_source_telemetry.h" -#include "mongo/db/pipeline/document_source_union_with.h" -#include "mongo/db/pipeline/document_source_unwind.h" -#include "mongo/s/query/document_source_merge_cursors.h" - namespace mongo { -template <class T> -bool DocumentSourceWalkerLegacy::visitHelper(const DocumentSource* source) { - const T* concrete = dynamic_cast<const T*>(source); - if (concrete == nullptr) { - return false; - } - - _postVisitor->visit(concrete); - return true; -} - -void DocumentSourceWalkerLegacy::walk(const Pipeline& pipeline) { - const Pipeline::SourceContainer& sources = pipeline.getSources(); - - if (_postVisitor != nullptr) { - for (auto it = sources.begin(); it != sources.end(); it++) { - // TODO: use acceptVisitor method when DocumentSources get ability to visit. - // source->acceptVisitor(*_preVisitor); - // - // For now, however, we use a crutch walker which performs a series of dynamic casts. - // Some types are commented out because of dependency issues (e.g. not in pipeline - // target but in query_exec target) - const DocumentSource* ds = it->get(); - const bool visited = visitHelper<DocumentSourceBucketAuto>(ds) || - visitHelper<DocumentSourceBucketAuto>(ds) || - visitHelper<DocumentSourceCollStats>(ds) || - visitHelper<DocumentSourceCurrentOp>(ds) || - // TODO: uncomment after fixing dependency - // visitHelper<DocumentSourceCursor>(ds) || - visitHelper<DocumentSourceExchange>(ds) || visitHelper<DocumentSourceFacet>(ds) || - visitHelper<DocumentSourceGeoNear>(ds) || - - // TODO: uncomment after fixing dependency - //! visitHelper<DocumentSourceGeoNearCursor>(ds) || - visitHelper<DocumentSourceGraphLookUp>(ds) || - visitHelper<DocumentSourceGroup>(ds) || visitHelper<DocumentSourceIndexStats>(ds) || - visitHelper<DocumentSourceInternalInhibitOptimization>(ds) || - visitHelper<DocumentSourceInternalShardFilter>(ds) || - visitHelper<DocumentSourceInternalSplitPipeline>(ds) || - visitHelper<DocumentSourceInternalUnpackBucket>(ds) || - visitHelper<DocumentSourceLimit>(ds) || - visitHelper<DocumentSourceListCachedAndActiveUsers>(ds) || - visitHelper<DocumentSourceListLocalSessions>(ds) || - visitHelper<DocumentSourceListSessions>(ds) || - visitHelper<DocumentSourceLookUp>(ds) || visitHelper<DocumentSourceMatch>(ds) || - visitHelper<DocumentSourceMerge>(ds) || - // TODO: uncomment after fixing dependency - // visitHelper<DocumentSourceMergeCursors>(ds) || - visitHelper<DocumentSourceOperationMetrics>(ds) || - visitHelper<DocumentSourceOut>(ds) || - visitHelper<DocumentSourcePlanCacheStats>(ds) || - visitHelper<DocumentSourceQueue>(ds) || visitHelper<DocumentSourceRedact>(ds) || - visitHelper<DocumentSourceSample>(ds) || - visitHelper<DocumentSourceSampleFromRandomCursor>(ds) || - visitHelper<DocumentSourceSequentialDocumentCache>(ds) || - visitHelper<DocumentSourceSingleDocumentTransformation>(ds) || - visitHelper<DocumentSourceSkip>(ds) || visitHelper<DocumentSourceSort>(ds) || - visitHelper<DocumentSourceTeeConsumer>(ds) || - visitHelper<DocumentSourceTelemetry>(ds) || - visitHelper<DocumentSourceUnionWith>(ds) || visitHelper<DocumentSourceUnwind>(ds) - // TODO: uncomment after fixing dependency - //&& visitHelper<DocumentSourceUpdateOnAddShard>(ds) - ; - - if (!visited) { - uasserted(ErrorCodes::InternalErrorNotSupported, - str::stream() << "Stage is not supported: " << ds->getSourceName()); - } - } - } - - // TODO: reverse for pre-visitor -} - void DocumentSourceWalker::walk(const Pipeline& pipeline) { for (auto&& ds : pipeline.getSources()) { // Perform double-dispatch based on the visitor context and document source types by diff --git a/src/mongo/db/pipeline/visitors/document_source_walker.h b/src/mongo/db/pipeline/visitors/document_source_walker.h index 0c8702ce9ad..e13f1e38d30 100644 --- a/src/mongo/db/pipeline/visitors/document_source_walker.h +++ b/src/mongo/db/pipeline/visitors/document_source_walker.h @@ -31,33 +31,11 @@ #include "mongo/db/pipeline/document_source.h" #include "mongo/db/pipeline/pipeline.h" -#include "mongo/db/pipeline/visitors/document_source_visitor.h" #include "mongo/db/pipeline/visitors/document_source_visitor_registry.h" namespace mongo { /** - * DEPRECATED: Use 'DocumentSourceWalker' instead. - * A document source walker. - * TODO SERVER-71943: Delete this class. - */ -class DocumentSourceWalkerLegacy final { -public: - DocumentSourceWalkerLegacy(DocumentSourceConstVisitor* preVisitor, - DocumentSourceConstVisitor* postVisitor) - : _preVisitor{preVisitor}, _postVisitor{postVisitor} {} - - void walk(const Pipeline& pipeline); - -private: - template <class T> - bool visitHelper(const DocumentSource* source); - - DocumentSourceConstVisitor* _preVisitor; - DocumentSourceConstVisitor* _postVisitor; -}; - -/** * A walker over a DocumentSource pipeline. See the DocumentSourceVisitorRegistry header for details * about why this walker does not use the typical "visitor" interface. */ |