summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/parsed_aggregation_projection.cpp
diff options
context:
space:
mode:
authorBernard Gorman <bernard.gorman@gmail.com>2018-06-18 17:44:58 +0100
committerBernard Gorman <bernard.gorman@gmail.com>2018-07-13 12:23:15 +0100
commit576d8360407738e0e4f7abf23b8335116f4ba125 (patch)
treee5937a553f19241aff8b38fb5c2d828449e42966 /src/mongo/db/pipeline/parsed_aggregation_projection.cpp
parentacdbc57731fa3176b0467425ece92e76a8d82958 (diff)
downloadmongo-576d8360407738e0e4f7abf23b8335116f4ba125.tar.gz
SERVER-35325 Implement key generation for "allPaths" indexes
Diffstat (limited to 'src/mongo/db/pipeline/parsed_aggregation_projection.cpp')
-rw-r--r--src/mongo/db/pipeline/parsed_aggregation_projection.cpp39
1 files changed, 27 insertions, 12 deletions
diff --git a/src/mongo/db/pipeline/parsed_aggregation_projection.cpp b/src/mongo/db/pipeline/parsed_aggregation_projection.cpp
index 5e106efe1e4..f600da57322 100644
--- a/src/mongo/db/pipeline/parsed_aggregation_projection.cpp
+++ b/src/mongo/db/pipeline/parsed_aggregation_projection.cpp
@@ -236,19 +236,30 @@ private:
elem.isBoolean() || elem.isNumber() ||
_parseMode != ProjectionParseMode::kBanComputedFields);
- if ((elem.isBoolean() || elem.isNumber()) && !elem.trueValue()) {
- // A top-level exclusion of "_id" is allowed in either an inclusion projection or an
- // exclusion projection, so doesn't affect '_parsedType'.
- if (pathToElem.fullPath() != "_id") {
- uassert(40178,
- str::stream() << "Bad projection specification, cannot exclude fields "
- "other than '_id' in an inclusion projection: "
+ if (pathToElem.fullPath() == "_id") {
+ // If the _id field is a computed value, then this must be an inclusion projection. If
+ // it is numeric or boolean, then this does not determine the projection type, due to
+ // the fact that inclusions may explicitly exclude _id and exclusions may include _id.
+ if (!elem.isBoolean() && !elem.isNumber()) {
+ uassert(ErrorCodes::FailedToParse,
+ str::stream() << "Bad projection specification, '_id' may not be a "
+ "computed field in an exclusion projection: "
<< _rawObj.toString(),
!_parsedType ||
- (*_parsedType ==
- TransformerInterface::TransformerType::kExclusionProjection));
- _parsedType = TransformerInterface::TransformerType::kExclusionProjection;
+ _parsedType ==
+ TransformerInterface::TransformerType::kInclusionProjection);
+ _parsedType = TransformerInterface::TransformerType::kInclusionProjection;
}
+ } else if ((elem.isBoolean() || elem.isNumber()) && !elem.trueValue()) {
+ // If this is an excluded field other than '_id', ensure that the projection type has
+ // not already been set to kInclusionProjection.
+ uassert(40178,
+ str::stream() << "Bad projection specification, cannot exclude fields "
+ "other than '_id' in an inclusion projection: "
+ << _rawObj.toString(),
+ !_parsedType || (*_parsedType ==
+ TransformerInterface::TransformerType::kExclusionProjection));
+ _parsedType = TransformerInterface::TransformerType::kExclusionProjection;
} else {
// A boolean true, a truthy numeric value, or any expression can only be used with an
// inclusion projection. Note that literal values like "string" or null are also treated
@@ -310,6 +321,8 @@ private:
std::unique_ptr<ParsedAggregationProjection> ParsedAggregationProjection::create(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
const BSONObj& spec,
+ ProjectionDefaultIdPolicy defaultIdPolicy,
+ ProjectionArrayRecursionPolicy arrayRecursionPolicy,
ProjectionParseMode parseMode) {
// Check that the specification was valid. Status returned is unspecific because validate()
// is used by the $addFields stage as well as $project.
@@ -325,8 +338,10 @@ std::unique_ptr<ParsedAggregationProjection> ParsedAggregationProjection::create
// We can't use make_unique() here, since the branches have different types.
std::unique_ptr<ParsedAggregationProjection> parsedProject(
projectionType == TransformerType::kInclusionProjection
- ? static_cast<ParsedAggregationProjection*>(new ParsedInclusionProjection(expCtx))
- : static_cast<ParsedAggregationProjection*>(new ParsedExclusionProjection(expCtx)));
+ ? static_cast<ParsedAggregationProjection*>(
+ new ParsedInclusionProjection(expCtx, defaultIdPolicy, arrayRecursionPolicy))
+ : static_cast<ParsedAggregationProjection*>(
+ new ParsedExclusionProjection(expCtx, defaultIdPolicy, arrayRecursionPolicy)));
// Actually parse the specification.
parsedProject->parse(spec);