diff options
author | Bernard Gorman <bernard.gorman@gmail.com> | 2017-06-17 01:19:22 +0100 |
---|---|---|
committer | Bernard Gorman <bernard.gorman@gmail.com> | 2017-06-17 16:12:32 +0100 |
commit | a5f0a84c79b6ce41fef33da920c62be0ecc8f07b (patch) | |
tree | 345557918938fe5de249aee2f8ad30684b80f65a /src/mongo/db/pipeline/pipeline.h | |
parent | 923ad3ba8160f2cd614e1258ef19294bd502af78 (diff) | |
download | mongo-a5f0a84c79b6ce41fef33da920c62be0ecc8f07b.tar.gz |
SERVER-19318 Do not validate $facet subpipelines against top-level pipeline namespace
Diffstat (limited to 'src/mongo/db/pipeline/pipeline.h')
-rw-r--r-- | src/mongo/db/pipeline/pipeline.h | 60 |
1 files changed, 56 insertions, 4 deletions
diff --git a/src/mongo/db/pipeline/pipeline.h b/src/mongo/db/pipeline/pipeline.h index 8a7f4211490..11f3bd916f1 100644 --- a/src/mongo/db/pipeline/pipeline.h +++ b/src/mongo/db/pipeline/pipeline.h @@ -97,9 +97,9 @@ public: }; /** - * Parses a Pipeline from a BSONElement representing a list of DocumentSources. Returns a non-OK - * status if it failed to parse. The returned pipeline is not optimized, but the caller may - * convert it to an optimized pipeline by calling optimizePipeline(). + * Parses a Pipeline from a vector of BSONObjs. Returns a non-OK status if it failed to parse. + * The returned pipeline is not optimized, but the caller may convert it to an optimized + * pipeline by calling optimizePipeline(). * * It is illegal to create a pipeline using an ExpressionContext which contains a collation that * will not be used during execution of the pipeline. Doing so may cause comparisons made during @@ -110,6 +110,17 @@ public: const boost::intrusive_ptr<ExpressionContext>& expCtx); /** + * Parses a $facet Pipeline from a vector of BSONObjs. Validation checks which are only relevant + * to top-level pipelines are skipped, and additional checks applicable to $facet pipelines are + * performed. Returns a non-OK status if it failed to parse. The returned pipeline is not + * optimized, but the caller may convert it to an optimized pipeline by calling + * optimizePipeline(). + */ + static StatusWith<std::unique_ptr<Pipeline, Pipeline::Deleter>> parseFacetPipeline( + const std::vector<BSONObj>& rawPipeline, + const boost::intrusive_ptr<ExpressionContext>& expCtx); + + /** * Creates a Pipeline from an existing SourceContainer. * * Returns a non-OK status if any stage is in an invalid position. For example, if an $out stage @@ -119,6 +130,15 @@ public: SourceContainer sources, const boost::intrusive_ptr<ExpressionContext>& expCtx); /** + * Creates a $facet Pipeline from an existing SourceContainer. + * + * Returns a non-OK status if any stage is invalid. For example, if the pipeline is empty or if + * any stage is an initial source. + */ + static StatusWith<std::unique_ptr<Pipeline, Pipeline::Deleter>> createFacetPipeline( + SourceContainer sources, const boost::intrusive_ptr<ExpressionContext>& expCtx); + + /** * Returns true if the provided aggregation command has a $out stage. */ static bool aggSupportsWriteConcern(const BSONObj& cmd); @@ -234,6 +254,24 @@ private: friend class Optimizations::Sharded; + /** + * Used by both Pipeline::parse() and Pipeline::parseFacetPipeline() to build and validate the + * pipeline. + */ + static StatusWith<std::unique_ptr<Pipeline, Pipeline::Deleter>> parseTopLevelOrFacetPipeline( + const std::vector<BSONObj>& rawPipeline, + const boost::intrusive_ptr<ExpressionContext>& expCtx, + const bool isFacetPipeline); + + /** + * Used by both Pipeline::create() and Pipeline::createFacetPipeline() to build and validate the + * pipeline. + */ + static StatusWith<std::unique_ptr<Pipeline, Pipeline::Deleter>> createTopLevelOrFacetPipeline( + SourceContainer sources, + const boost::intrusive_ptr<ExpressionContext>& expCtx, + const bool isSubPipeline); + Pipeline(const boost::intrusive_ptr<ExpressionContext>& pCtx); Pipeline(SourceContainer stages, const boost::intrusive_ptr<ExpressionContext>& pCtx); @@ -257,7 +295,21 @@ private: * if an $out stage is present then it must come last in the pipeline, while initial stages such * as $indexStats must be at the start. */ - Status validate() const; + Status validatePipeline() const; + + /** + * Returns a non-OK status if the $facet pipeline fails any of a set of semantic checks. For + * example, the pipeline cannot be empty and may not contain any initial stages. + */ + Status validateFacetPipeline() const; + + /** + * Helper method which validates that each stage in pipeline is in a legal position. For + * example, $out must be at the end, while a $match stage with a text query must be at the + * start. Note that this method accepts an initial source as the first stage, which is illegal + * for $facet pipelines. + */ + Status ensureAllStagesAreInLegalPositions() const; SourceContainer _sources; |