summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/pipeline.h
diff options
context:
space:
mode:
authorBernard Gorman <bernard.gorman@gmail.com>2017-06-17 01:19:22 +0100
committerBernard Gorman <bernard.gorman@gmail.com>2017-06-17 16:12:32 +0100
commita5f0a84c79b6ce41fef33da920c62be0ecc8f07b (patch)
tree345557918938fe5de249aee2f8ad30684b80f65a /src/mongo/db/pipeline/pipeline.h
parent923ad3ba8160f2cd614e1258ef19294bd502af78 (diff)
downloadmongo-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.h60
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;