1 
2 /**
3  *    Copyright (C) 2018-present MongoDB, Inc.
4  *
5  *    This program is free software: you can redistribute it and/or modify
6  *    it under the terms of the Server Side Public License, version 1,
7  *    as published by MongoDB, Inc.
8  *
9  *    This program is distributed in the hope that it will be useful,
10  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *    Server Side Public License for more details.
13  *
14  *    You should have received a copy of the Server Side Public License
15  *    along with this program. If not, see
16  *    <http://www.mongodb.com/licensing/server-side-public-license>.
17  *
18  *    As a special exception, the copyright holders give permission to link the
19  *    code of portions of this program with the OpenSSL library under certain
20  *    conditions as described in each individual source file and distribute
21  *    linked combinations including the program with the OpenSSL library. You
22  *    must comply with the Server Side Public License in all respects for
23  *    all of the code used other than as permitted herein. If you modify file(s)
24  *    with this exception, you may extend this exception to your version of the
25  *    file(s), but you are not obligated to do so. If you do not wish to do so,
26  *    delete this exception statement from your version. If you delete this
27  *    exception statement from all source files in the program, then also delete
28  *    it in the license file.
29  */
30 
31 #pragma once
32 
33 #include <boost/intrusive_ptr.hpp>
34 #include <boost/optional/optional.hpp>
35 
36 #include "mongo/db/catalog/collection.h"
37 #include "mongo/db/exec/plan_stage.h"
38 #include "mongo/db/exec/plan_stats.h"
39 #include "mongo/db/pipeline/pipeline.h"
40 #include "mongo/db/query/plan_summary_stats.h"
41 #include "mongo/db/record_id.h"
42 #include "mongo/util/assert_util.h"
43 
44 namespace mongo {
45 
46 /**
47  * Stage for pulling results out from an aggregation pipeline.
48  */
49 class PipelineProxyStage final : public PlanStage {
50 public:
51     PipelineProxyStage(OperationContext* opCtx,
52                        std::unique_ptr<Pipeline, Pipeline::Deleter> pipeline,
53                        WorkingSet* ws);
54 
55     PlanStage::StageState doWork(WorkingSetID* out) final;
56 
57     bool isEOF() final;
58 
59     //
60     // Manage our OperationContext.
61     //
62     void doDetachFromOperationContext() final;
63     void doReattachToOperationContext() final;
64 
65     // Returns empty PlanStageStats object
66     std::unique_ptr<PlanStageStats> getStats() final;
67 
68     // Not used.
getSpecificStats()69     SpecificStats* getSpecificStats() const final {
70         MONGO_UNREACHABLE;
71     }
72 
doInvalidate(OperationContext * opCtx,const RecordId & rid,InvalidationType type)73     void doInvalidate(OperationContext* opCtx, const RecordId& rid, InvalidationType type) final {
74         // A PlanExecutor with a PipelineProxyStage should be registered with the global cursor
75         // manager, so should not receive invalidations.
76         MONGO_UNREACHABLE;
77     }
78 
79     /**
80      * Pass through the last oplog timestamp from the proxied pipeline.
81      */
82     Timestamp getLatestOplogTimestamp() const;
83 
84     std::string getPlanSummaryStr() const;
85     void getPlanSummaryStats(PlanSummaryStats* statsOut) const;
86 
stageType()87     StageType stageType() const final {
88         return STAGE_PIPELINE_PROXY;
89     }
90 
91     static const char* kStageType;
92 
93 protected:
94     void doDispose() final;
95 
96 private:
97     boost::optional<BSONObj> getNextBson();
98 
99     // Things in the _stash should be returned before pulling items from _pipeline.
100     std::unique_ptr<Pipeline, Pipeline::Deleter> _pipeline;
101     std::vector<BSONObj> _stash;
102     const bool _includeMetaData;
103 
104     // When the aggregation request is from a 3.4 mongos, the merge may happen on a 3.4 shard (which
105     // does not understand sort key metadata), so we should not serialize the sort key, and
106     // '_includeSortKey' is set to false.
107     // TODO SERVER-30924: remove this.
108     const bool _includeSortKey;
109 
110     // Not owned by us.
111     WorkingSet* _ws;
112 };
113 
114 }  // namespace mongo
115