summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/expression.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/pipeline/expression.h')
-rw-r--r--src/mongo/db/pipeline/expression.h428
1 files changed, 336 insertions, 92 deletions
diff --git a/src/mongo/db/pipeline/expression.h b/src/mongo/db/pipeline/expression.h
index 00e771784c2..ef9a3ae3f19 100644
--- a/src/mongo/db/pipeline/expression.h
+++ b/src/mongo/db/pipeline/expression.h
@@ -172,8 +172,8 @@ private:
class Expression : public IntrusiveCounterUnsigned {
public:
- using Parser =
- stdx::function<boost::intrusive_ptr<Expression>(BSONElement, const VariablesParseState&)>;
+ using Parser = stdx::function<boost::intrusive_ptr<Expression>(
+ const boost::intrusive_ptr<ExpressionContext>&, BSONElement, const VariablesParseState&)>;
virtual ~Expression(){};
@@ -235,8 +235,10 @@ public:
* Calls parseExpression() on any sub-document (including possibly the entire document) which
* consists of a single field name starting with a '$'.
*/
- static boost::intrusive_ptr<Expression> parseObject(BSONObj obj,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parseObject(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONObj obj,
+ const VariablesParseState& vps);
/**
* Parses a BSONObj which has already been determined to be a functional expression.
@@ -244,8 +246,10 @@ public:
* Throws an error if 'obj' does not contain exactly one field, or if that field's name does not
* match a registered expression name.
*/
- static boost::intrusive_ptr<Expression> parseExpression(BSONObj obj,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parseExpression(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONObj obj,
+ const VariablesParseState& vps);
/**
* Parses a BSONElement which is an argument to an Expression.
@@ -254,8 +258,10 @@ public:
* parseObject(), ExpressionFieldPath::parse(), ExpressionArray::parse(), or
* ExpressionConstant::parse() as necessary.
*/
- static boost::intrusive_ptr<Expression> parseOperand(BSONElement exprElement,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parseOperand(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement exprElement,
+ const VariablesParseState& vps);
/*
Produce a field path std::string with the field prefix removed.
@@ -282,24 +288,10 @@ public:
*/
static void registerExpression(std::string key, Parser parser);
- /**
- * Injects the ExpressionContext so that it may be used during evaluation of the Expression.
- * Construction of expressions is done at parse time, but the ExpressionContext isn't finalized
- * until later, at which point it is injected using this method.
- */
- void injectExpressionContext(const boost::intrusive_ptr<ExpressionContext>& expCtx) {
- _expCtx = expCtx;
- doInjectExpressionContext();
- }
-
protected:
- typedef std::vector<boost::intrusive_ptr<Expression>> ExpressionVector;
+ Expression(const boost::intrusive_ptr<ExpressionContext>& expCtx) : _expCtx(expCtx) {}
- /**
- * Expressions which need to update their internal state when attaching to a new
- * ExpressionContext should override this method.
- */
- virtual void doInjectExpressionContext() {}
+ typedef std::vector<boost::intrusive_ptr<Expression>> ExpressionVector;
const boost::intrusive_ptr<ExpressionContext>& getExpressionContext() const {
return _expCtx;
@@ -344,12 +336,13 @@ public:
/// Allow subclasses the opportunity to validate arguments at parse time.
virtual void validateArguments(const ExpressionVector& args) const {}
- static ExpressionVector parseArguments(BSONElement bsonExpr, const VariablesParseState& vps);
-
- void doInjectExpressionContext() final;
+ static ExpressionVector parseArguments(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement bsonExpr,
+ const VariablesParseState& vps);
protected:
- ExpressionNary() {}
+ explicit ExpressionNary(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : Expression(expCtx) {}
ExpressionVector vpOperand;
};
@@ -358,19 +351,29 @@ protected:
template <typename SubClass>
class ExpressionNaryBase : public ExpressionNary {
public:
- static boost::intrusive_ptr<Expression> parse(BSONElement bsonExpr,
- const VariablesParseState& vps) {
- boost::intrusive_ptr<ExpressionNaryBase> expr = new SubClass();
- ExpressionVector args = parseArguments(bsonExpr, vps);
+ static boost::intrusive_ptr<Expression> parse(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement bsonExpr,
+ const VariablesParseState& vps) {
+ boost::intrusive_ptr<ExpressionNaryBase> expr = new SubClass(expCtx);
+ ExpressionVector args = parseArguments(expCtx, bsonExpr, vps);
expr->validateArguments(args);
expr->vpOperand = args;
return expr;
}
+
+protected:
+ explicit ExpressionNaryBase(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionNary(expCtx) {}
};
/// Inherit from this class if your expression takes a variable number of arguments.
template <typename SubClass>
-class ExpressionVariadic : public ExpressionNaryBase<SubClass> {};
+class ExpressionVariadic : public ExpressionNaryBase<SubClass> {
+public:
+ explicit ExpressionVariadic(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionNaryBase<SubClass>(expCtx) {}
+};
/**
* Inherit from this class if your expression can take a range of arguments, e.g. if it has some
@@ -379,6 +382,9 @@ class ExpressionVariadic : public ExpressionNaryBase<SubClass> {};
template <typename SubClass, int MinArgs, int MaxArgs>
class ExpressionRangedArity : public ExpressionNaryBase<SubClass> {
public:
+ explicit ExpressionRangedArity(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionNaryBase<SubClass>(expCtx) {}
+
void validateArguments(const Expression::ExpressionVector& args) const override {
uassert(28667,
mongoutils::str::stream() << "Expression " << this->getOpName()
@@ -397,6 +403,9 @@ public:
template <typename SubClass, int NArgs>
class ExpressionFixedArity : public ExpressionNaryBase<SubClass> {
public:
+ explicit ExpressionFixedArity(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionNaryBase<SubClass>(expCtx) {}
+
void validateArguments(const Expression::ExpressionVector& args) const override {
uassert(16020,
mongoutils::str::stream() << "Expression " << this->getOpName() << " takes exactly "
@@ -416,9 +425,11 @@ template <typename Accumulator>
class ExpressionFromAccumulator
: public ExpressionVariadic<ExpressionFromAccumulator<Accumulator>> {
public:
+ explicit ExpressionFromAccumulator(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionVariadic<ExpressionFromAccumulator<Accumulator>>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final {
- Accumulator accum;
- accum.injectExpressionContext(this->getExpressionContext());
+ Accumulator accum(this->getExpressionContext());
const size_t n = this->vpOperand.size();
// If a single array arg is given, loop through it passing each member to the accumulator.
// If a single, non-array arg is given, pass it directly to the accumulator.
@@ -446,15 +457,15 @@ public:
if (this->vpOperand.size() == 1) {
return false;
}
- return Accumulator().isAssociative();
+ return Accumulator(this->getExpressionContext()).isAssociative();
}
bool isCommutative() const final {
- return Accumulator().isCommutative();
+ return Accumulator(this->getExpressionContext()).isCommutative();
}
const char* getOpName() const final {
- return Accumulator().getOpName();
+ return Accumulator(this->getExpressionContext()).getOpName();
}
};
@@ -464,6 +475,9 @@ public:
template <typename SubClass>
class ExpressionSingleNumericArg : public ExpressionFixedArity<SubClass, 1> {
public:
+ explicit ExpressionSingleNumericArg(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<SubClass, 1>(expCtx) {}
+
virtual ~ExpressionSingleNumericArg() {}
Value evaluateInternal(Variables* vars) const final {
@@ -484,6 +498,10 @@ public:
class ExpressionAbs final : public ExpressionSingleNumericArg<ExpressionAbs> {
+public:
+ explicit ExpressionAbs(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionSingleNumericArg<ExpressionAbs>(expCtx) {}
+
Value evaluateNumericArg(const Value& numericArg) const final;
const char* getOpName() const final;
};
@@ -491,6 +509,9 @@ class ExpressionAbs final : public ExpressionSingleNumericArg<ExpressionAbs> {
class ExpressionAdd final : public ExpressionVariadic<ExpressionAdd> {
public:
+ explicit ExpressionAdd(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionVariadic<ExpressionAdd>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -506,6 +527,9 @@ public:
class ExpressionAllElementsTrue final : public ExpressionFixedArity<ExpressionAllElementsTrue, 1> {
public:
+ explicit ExpressionAllElementsTrue(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionAllElementsTrue, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -513,6 +537,9 @@ public:
class ExpressionAnd final : public ExpressionVariadic<ExpressionAnd> {
public:
+ explicit ExpressionAnd(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionVariadic<ExpressionAnd>(expCtx) {}
+
boost::intrusive_ptr<Expression> optimize() final;
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -529,6 +556,9 @@ public:
class ExpressionAnyElementTrue final : public ExpressionFixedArity<ExpressionAnyElementTrue, 1> {
public:
+ explicit ExpressionAnyElementTrue(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionAnyElementTrue, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -536,7 +566,9 @@ public:
class ExpressionArray final : public ExpressionVariadic<ExpressionArray> {
public:
- // virtuals from ExpressionNary
+ explicit ExpressionArray(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionVariadic<ExpressionArray>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
Value serialize(bool explain) const final;
const char* getOpName() const final;
@@ -545,6 +577,9 @@ public:
class ExpressionArrayElemAt final : public ExpressionFixedArity<ExpressionArrayElemAt, 2> {
public:
+ explicit ExpressionArrayElemAt(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionArrayElemAt, 2>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -552,6 +587,9 @@ public:
class ExpressionCeil final : public ExpressionSingleNumericArg<ExpressionCeil> {
public:
+ explicit ExpressionCeil(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionSingleNumericArg<ExpressionCeil>(expCtx) {}
+
Value evaluateNumericArg(const Value& numericArg) const final;
const char* getOpName() const final;
};
@@ -568,10 +606,9 @@ public:
const boost::intrusive_ptr<ExpressionContext>& expCtx,
const boost::intrusive_ptr<Expression>& pExpression);
- void doInjectExpressionContext() final;
-
private:
- explicit ExpressionCoerceToBool(const boost::intrusive_ptr<Expression>& pExpression);
+ ExpressionCoerceToBool(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ const boost::intrusive_ptr<Expression>& pExpression);
boost::intrusive_ptr<Expression> pExpression;
};
@@ -593,16 +630,20 @@ public:
CMP = 6, // return -1, 0, 1 for a < b, a == b, a > b
};
+ ExpressionCompare(const boost::intrusive_ptr<ExpressionContext>& expCtx, CmpOp cmpOp)
+ : ExpressionFixedArity<ExpressionCompare, 2>(expCtx), cmpOp(cmpOp) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
- static boost::intrusive_ptr<Expression> parse(BSONElement bsonExpr,
- const VariablesParseState& vps,
- CmpOp cmpOp);
-
- explicit ExpressionCompare(CmpOp cmpOp);
+ static boost::intrusive_ptr<Expression> parse(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement bsonExpr,
+ const VariablesParseState& vps,
+ CmpOp cmpOp);
static boost::intrusive_ptr<ExpressionCompare> create(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
CmpOp cmpOp,
const boost::intrusive_ptr<Expression>& exprLeft,
const boost::intrusive_ptr<Expression>& exprRight);
@@ -614,6 +655,9 @@ private:
class ExpressionConcat final : public ExpressionVariadic<ExpressionConcat> {
public:
+ explicit ExpressionConcat(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionVariadic<ExpressionConcat>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -625,6 +669,9 @@ public:
class ExpressionConcatArrays final : public ExpressionVariadic<ExpressionConcatArrays> {
public:
+ explicit ExpressionConcatArrays(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionVariadic<ExpressionConcatArrays>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -635,13 +682,19 @@ public:
class ExpressionCond final : public ExpressionFixedArity<ExpressionCond, 3> {
- typedef ExpressionFixedArity<ExpressionCond, 3> Base;
-
public:
+ explicit ExpressionCond(const boost::intrusive_ptr<ExpressionContext>& expCtx) : Base(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
- static boost::intrusive_ptr<Expression> parse(BSONElement expr, const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
+
+private:
+ typedef ExpressionFixedArity<ExpressionCond, 3> Base;
};
@@ -657,8 +710,10 @@ public:
static boost::intrusive_ptr<ExpressionConstant> create(
const boost::intrusive_ptr<ExpressionContext>& expCtx, const Value& pValue);
- static boost::intrusive_ptr<Expression> parse(BSONElement bsonExpr,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement bsonExpr,
+ const VariablesParseState& vps);
/*
Get the constant value represented by this Expression.
@@ -670,7 +725,7 @@ public:
}
private:
- explicit ExpressionConstant(const Value& pValue);
+ ExpressionConstant(const boost::intrusive_ptr<ExpressionContext>& expCtx, const Value& pValue);
Value pValue;
};
@@ -682,12 +737,14 @@ public:
Value evaluateInternal(Variables* vars) const final;
void addDependencies(DepsTracker* deps) const final;
- static boost::intrusive_ptr<Expression> parse(BSONElement expr, const VariablesParseState& vps);
-
- void doInjectExpressionContext() final;
+ static boost::intrusive_ptr<Expression> parse(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
private:
- ExpressionDateToString(const std::string& format, // the format string
+ ExpressionDateToString(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ const std::string& format, // the format string
boost::intrusive_ptr<Expression> date); // the date to format
// Will uassert on invalid data
@@ -705,6 +762,9 @@ private:
class ExpressionDayOfMonth final : public ExpressionFixedArity<ExpressionDayOfMonth, 1> {
public:
+ explicit ExpressionDayOfMonth(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionDayOfMonth, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -716,6 +776,9 @@ public:
class ExpressionDayOfWeek final : public ExpressionFixedArity<ExpressionDayOfWeek, 1> {
public:
+ explicit ExpressionDayOfWeek(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionDayOfWeek, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -728,6 +791,9 @@ public:
class ExpressionDayOfYear final : public ExpressionFixedArity<ExpressionDayOfYear, 1> {
public:
+ explicit ExpressionDayOfYear(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionDayOfYear, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -740,12 +806,19 @@ public:
class ExpressionDivide final : public ExpressionFixedArity<ExpressionDivide, 2> {
public:
+ explicit ExpressionDivide(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionDivide, 2>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
class ExpressionExp final : public ExpressionSingleNumericArg<ExpressionExp> {
+public:
+ explicit ExpressionExp(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionSingleNumericArg<ExpressionExp>(expCtx) {}
+
Value evaluateNumericArg(const Value& numericArg) const final;
const char* getOpName() const final;
};
@@ -771,18 +844,23 @@ public:
indicator
@returns the newly created field path expression
*/
- static boost::intrusive_ptr<ExpressionFieldPath> create(const std::string& fieldPath);
+ static boost::intrusive_ptr<ExpressionFieldPath> create(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx, const std::string& fieldPath);
/// Like create(), but works with the raw std::string from the user with the "$" prefixes.
- static boost::intrusive_ptr<ExpressionFieldPath> parse(const std::string& raw,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<ExpressionFieldPath> parse(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ const std::string& raw,
+ const VariablesParseState& vps);
const FieldPath& getFieldPath() const {
return _fieldPath;
}
private:
- ExpressionFieldPath(const std::string& fieldPath, Variables::Id variable);
+ ExpressionFieldPath(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ const std::string& fieldPath,
+ Variables::Id variable);
/*
Internal implementation of evaluateInternal(), used recursively.
@@ -814,12 +892,14 @@ public:
Value evaluateInternal(Variables* vars) const final;
void addDependencies(DepsTracker* deps) const final;
- static boost::intrusive_ptr<Expression> parse(BSONElement expr, const VariablesParseState& vps);
-
- void doInjectExpressionContext() final;
+ static boost::intrusive_ptr<Expression> parse(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
private:
- ExpressionFilter(std::string varName,
+ ExpressionFilter(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ std::string varName,
Variables::Id varId,
boost::intrusive_ptr<Expression> input,
boost::intrusive_ptr<Expression> filter);
@@ -837,6 +917,9 @@ private:
class ExpressionFloor final : public ExpressionSingleNumericArg<ExpressionFloor> {
public:
+ explicit ExpressionFloor(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionSingleNumericArg<ExpressionFloor>(expCtx) {}
+
Value evaluateNumericArg(const Value& numericArg) const final;
const char* getOpName() const final;
};
@@ -844,6 +927,9 @@ public:
class ExpressionHour final : public ExpressionFixedArity<ExpressionHour, 1> {
public:
+ explicit ExpressionHour(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionHour, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -855,6 +941,9 @@ public:
class ExpressionIfNull final : public ExpressionFixedArity<ExpressionIfNull, 2> {
public:
+ explicit ExpressionIfNull(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionIfNull, 2>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -862,6 +951,9 @@ public:
class ExpressionIn final : public ExpressionFixedArity<ExpressionIn, 2> {
public:
+ explicit ExpressionIn(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionIn, 2>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -869,6 +961,9 @@ public:
class ExpressionIndexOfArray final : public ExpressionRangedArity<ExpressionIndexOfArray, 2, 4> {
public:
+ explicit ExpressionIndexOfArray(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionRangedArity<ExpressionIndexOfArray, 2, 4>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -876,6 +971,9 @@ public:
class ExpressionIndexOfBytes final : public ExpressionRangedArity<ExpressionIndexOfBytes, 2, 4> {
public:
+ explicit ExpressionIndexOfBytes(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionRangedArity<ExpressionIndexOfBytes, 2, 4>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -886,6 +984,9 @@ public:
*/
class ExpressionIndexOfCP final : public ExpressionRangedArity<ExpressionIndexOfCP, 2, 4> {
public:
+ explicit ExpressionIndexOfCP(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionRangedArity<ExpressionIndexOfCP, 2, 4>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -898,9 +999,10 @@ public:
Value evaluateInternal(Variables* vars) const final;
void addDependencies(DepsTracker* deps) const final;
- static boost::intrusive_ptr<Expression> parse(BSONElement expr, const VariablesParseState& vps);
-
- void doInjectExpressionContext() final;
+ static boost::intrusive_ptr<Expression> parse(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
struct NameAndExpression {
NameAndExpression() {}
@@ -914,23 +1016,37 @@ public:
typedef std::map<Variables::Id, NameAndExpression> VariableMap;
private:
- ExpressionLet(const VariableMap& vars, boost::intrusive_ptr<Expression> subExpression);
+ ExpressionLet(const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ const VariableMap& vars,
+ boost::intrusive_ptr<Expression> subExpression);
VariableMap _variables;
boost::intrusive_ptr<Expression> _subExpression;
};
class ExpressionLn final : public ExpressionSingleNumericArg<ExpressionLn> {
+public:
+ explicit ExpressionLn(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionSingleNumericArg<ExpressionLn>(expCtx) {}
+
Value evaluateNumericArg(const Value& numericArg) const final;
const char* getOpName() const final;
};
class ExpressionLog final : public ExpressionFixedArity<ExpressionLog, 2> {
+public:
+ explicit ExpressionLog(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionLog, 2>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
class ExpressionLog10 final : public ExpressionSingleNumericArg<ExpressionLog10> {
+public:
+ explicit ExpressionLog10(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionSingleNumericArg<ExpressionLog10>(expCtx) {}
+
Value evaluateNumericArg(const Value& numericArg) const final;
const char* getOpName() const final;
};
@@ -942,12 +1058,14 @@ public:
Value evaluateInternal(Variables* vars) const final;
void addDependencies(DepsTracker* deps) const final;
- static boost::intrusive_ptr<Expression> parse(BSONElement expr, const VariablesParseState& vps);
-
- void doInjectExpressionContext() final;
+ static boost::intrusive_ptr<Expression> parse(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
private:
ExpressionMap(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
const std::string& varName, // name of variable to set
Variables::Id varId, // id of variable to set
boost::intrusive_ptr<Expression> input, // yields array to iterate
@@ -965,7 +1083,10 @@ public:
Value evaluateInternal(Variables* vars) const final;
void addDependencies(DepsTracker* deps) const final;
- static boost::intrusive_ptr<Expression> parse(BSONElement expr, const VariablesParseState& vps);
+ static boost::intrusive_ptr<Expression> parse(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement expr,
+ const VariablesParseState& vps);
private:
enum MetaType {
@@ -973,13 +1094,16 @@ private:
RAND_VAL,
};
- ExpressionMeta(MetaType metaType);
+ ExpressionMeta(const boost::intrusive_ptr<ExpressionContext>& expCtx, MetaType metaType);
MetaType _metaType;
};
class ExpressionMillisecond final : public ExpressionFixedArity<ExpressionMillisecond, 1> {
public:
+ explicit ExpressionMillisecond(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionMillisecond, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -989,6 +1113,9 @@ public:
class ExpressionMinute final : public ExpressionFixedArity<ExpressionMinute, 1> {
public:
+ explicit ExpressionMinute(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionMinute, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -1000,6 +1127,9 @@ public:
class ExpressionMod final : public ExpressionFixedArity<ExpressionMod, 2> {
public:
+ explicit ExpressionMod(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionMod, 2>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -1007,6 +1137,9 @@ public:
class ExpressionMultiply final : public ExpressionVariadic<ExpressionMultiply> {
public:
+ explicit ExpressionMultiply(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionVariadic<ExpressionMultiply>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -1022,6 +1155,9 @@ public:
class ExpressionMonth final : public ExpressionFixedArity<ExpressionMonth, 1> {
public:
+ explicit ExpressionMonth(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionMonth, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -1034,6 +1170,9 @@ public:
class ExpressionNot final : public ExpressionFixedArity<ExpressionNot, 1> {
public:
+ explicit ExpressionNot(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionNot, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -1055,13 +1194,16 @@ public:
Value serialize(bool explain) const final;
static boost::intrusive_ptr<ExpressionObject> create(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
std::vector<std::pair<std::string, boost::intrusive_ptr<Expression>>>&& expressions);
/**
* Parses and constructs an ExpressionObject from 'obj'.
*/
- static boost::intrusive_ptr<ExpressionObject> parse(BSONObj obj,
- const VariablesParseState& vps);
+ static boost::intrusive_ptr<ExpressionObject> parse(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONObj obj,
+ const VariablesParseState& vps);
/**
* This ExpressionObject must outlive the returned vector.
@@ -1071,10 +1213,9 @@ public:
return _expressions;
}
- void doInjectExpressionContext() final;
-
private:
ExpressionObject(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
std::vector<std::pair<std::string, boost::intrusive_ptr<Expression>>>&& expressions);
// The mapping from field name to expression within this object. This needs to respect the order
@@ -1085,6 +1226,9 @@ private:
class ExpressionOr final : public ExpressionVariadic<ExpressionOr> {
public:
+ explicit ExpressionOr(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionVariadic<ExpressionOr>(expCtx) {}
+
boost::intrusive_ptr<Expression> optimize() final;
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -1100,7 +1244,11 @@ public:
class ExpressionPow final : public ExpressionFixedArity<ExpressionPow, 2> {
public:
- static boost::intrusive_ptr<Expression> create(Value base, Value exp);
+ explicit ExpressionPow(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionPow, 2>(expCtx) {}
+
+ static boost::intrusive_ptr<Expression> create(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx, Value base, Value exp);
private:
Value evaluateInternal(Variables* vars) const final;
@@ -1109,6 +1257,10 @@ private:
class ExpressionRange final : public ExpressionRangedArity<ExpressionRange, 2, 3> {
+public:
+ explicit ExpressionRange(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionRangedArity<ExpressionRange, 2, 3>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -1116,15 +1268,18 @@ class ExpressionRange final : public ExpressionRangedArity<ExpressionRange, 2, 3
class ExpressionReduce final : public Expression {
public:
+ explicit ExpressionReduce(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : Expression(expCtx) {}
+
void addDependencies(DepsTracker* deps) const final;
Value evaluateInternal(Variables* vars) const final;
boost::intrusive_ptr<Expression> optimize() final;
- static boost::intrusive_ptr<Expression> parse(BSONElement expr,
- const VariablesParseState& vpsIn);
+ static boost::intrusive_ptr<Expression> parse(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement expr,
+ const VariablesParseState& vpsIn);
Value serialize(bool explain) const final;
- void doInjectExpressionContext() final;
-
private:
boost::intrusive_ptr<Expression> _input;
boost::intrusive_ptr<Expression> _initial;
@@ -1137,6 +1292,9 @@ private:
class ExpressionSecond final : public ExpressionFixedArity<ExpressionSecond, 1> {
public:
+ explicit ExpressionSecond(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionSecond, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -1148,6 +1306,9 @@ public:
class ExpressionSetDifference final : public ExpressionFixedArity<ExpressionSetDifference, 2> {
public:
+ explicit ExpressionSetDifference(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionSetDifference, 2>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -1155,6 +1316,9 @@ public:
class ExpressionSetEquals final : public ExpressionVariadic<ExpressionSetEquals> {
public:
+ explicit ExpressionSetEquals(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionVariadic<ExpressionSetEquals>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
void validateArguments(const ExpressionVector& args) const final;
@@ -1163,6 +1327,9 @@ public:
class ExpressionSetIntersection final : public ExpressionVariadic<ExpressionSetIntersection> {
public:
+ explicit ExpressionSetIntersection(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionVariadic<ExpressionSetIntersection>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -1179,6 +1346,9 @@ public:
// Not final, inherited from for optimizations.
class ExpressionSetIsSubset : public ExpressionFixedArity<ExpressionSetIsSubset, 2> {
public:
+ explicit ExpressionSetIsSubset(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionSetIsSubset, 2>(expCtx) {}
+
boost::intrusive_ptr<Expression> optimize() override;
Value evaluateInternal(Variables* vars) const override;
const char* getOpName() const final;
@@ -1190,7 +1360,9 @@ private:
class ExpressionSetUnion final : public ExpressionVariadic<ExpressionSetUnion> {
public:
- // intrusive_ptr<Expression> optimize() final;
+ explicit ExpressionSetUnion(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionVariadic<ExpressionSetUnion>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -1206,6 +1378,9 @@ public:
class ExpressionSize final : public ExpressionFixedArity<ExpressionSize, 1> {
public:
+ explicit ExpressionSize(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionSize, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -1213,6 +1388,9 @@ public:
class ExpressionReverseArray final : public ExpressionFixedArity<ExpressionReverseArray, 1> {
public:
+ explicit ExpressionReverseArray(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionReverseArray, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -1220,6 +1398,9 @@ public:
class ExpressionSlice final : public ExpressionRangedArity<ExpressionSlice, 2, 3> {
public:
+ explicit ExpressionSlice(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionRangedArity<ExpressionSlice, 2, 3>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -1227,6 +1408,9 @@ public:
class ExpressionIsArray final : public ExpressionFixedArity<ExpressionIsArray, 1> {
public:
+ explicit ExpressionIsArray(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionIsArray, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -1234,12 +1418,19 @@ public:
class ExpressionSplit final : public ExpressionFixedArity<ExpressionSplit, 2> {
public:
+ explicit ExpressionSplit(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionSplit, 2>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
class ExpressionSqrt final : public ExpressionSingleNumericArg<ExpressionSqrt> {
+public:
+ explicit ExpressionSqrt(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionSingleNumericArg<ExpressionSqrt>(expCtx) {}
+
Value evaluateNumericArg(const Value& numericArg) const final;
const char* getOpName() const final;
};
@@ -1247,6 +1438,9 @@ class ExpressionSqrt final : public ExpressionSingleNumericArg<ExpressionSqrt> {
class ExpressionStrcasecmp final : public ExpressionFixedArity<ExpressionStrcasecmp, 2> {
public:
+ explicit ExpressionStrcasecmp(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionStrcasecmp, 2>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -1254,6 +1448,9 @@ public:
class ExpressionSubstrBytes : public ExpressionFixedArity<ExpressionSubstrBytes, 3> {
public:
+ explicit ExpressionSubstrBytes(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionSubstrBytes, 3>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const;
};
@@ -1261,18 +1458,29 @@ public:
class ExpressionSubstrCP final : public ExpressionFixedArity<ExpressionSubstrCP, 3> {
public:
+ explicit ExpressionSubstrCP(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionSubstrCP, 3>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
class ExpressionStrLenBytes final : public ExpressionFixedArity<ExpressionStrLenBytes, 1> {
+public:
+ explicit ExpressionStrLenBytes(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionStrLenBytes, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
class ExpressionStrLenCP final : public ExpressionFixedArity<ExpressionStrLenCP, 1> {
+public:
+ explicit ExpressionStrLenCP(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionStrLenCP, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -1280,6 +1488,9 @@ class ExpressionStrLenCP final : public ExpressionFixedArity<ExpressionStrLenCP,
class ExpressionSubtract final : public ExpressionFixedArity<ExpressionSubtract, 2> {
public:
+ explicit ExpressionSubtract(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionSubtract, 2>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -1287,15 +1498,18 @@ public:
class ExpressionSwitch final : public Expression {
public:
+ explicit ExpressionSwitch(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : Expression(expCtx) {}
+
void addDependencies(DepsTracker* deps) const final;
Value evaluateInternal(Variables* vars) const final;
boost::intrusive_ptr<Expression> optimize() final;
- static boost::intrusive_ptr<Expression> parse(BSONElement expr,
- const VariablesParseState& vpsIn);
+ static boost::intrusive_ptr<Expression> parse(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement expr,
+ const VariablesParseState& vpsIn);
Value serialize(bool explain) const final;
- void doInjectExpressionContext() final;
-
private:
using ExpressionPair =
std::pair<boost::intrusive_ptr<Expression>, boost::intrusive_ptr<Expression>>;
@@ -1307,6 +1521,9 @@ private:
class ExpressionToLower final : public ExpressionFixedArity<ExpressionToLower, 1> {
public:
+ explicit ExpressionToLower(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionToLower, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -1314,6 +1531,9 @@ public:
class ExpressionToUpper final : public ExpressionFixedArity<ExpressionToUpper, 1> {
public:
+ explicit ExpressionToUpper(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionToUpper, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -1321,6 +1541,9 @@ public:
class ExpressionTrunc final : public ExpressionSingleNumericArg<ExpressionTrunc> {
public:
+ explicit ExpressionTrunc(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionSingleNumericArg<ExpressionTrunc>(expCtx) {}
+
Value evaluateNumericArg(const Value& numericArg) const final;
const char* getOpName() const final;
};
@@ -1328,6 +1551,9 @@ public:
class ExpressionType final : public ExpressionFixedArity<ExpressionType, 1> {
public:
+ explicit ExpressionType(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionType, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
};
@@ -1335,6 +1561,9 @@ public:
class ExpressionWeek final : public ExpressionFixedArity<ExpressionWeek, 1> {
public:
+ explicit ExpressionWeek(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionWeek, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -1344,6 +1573,9 @@ public:
class ExpressionIsoWeekYear final : public ExpressionFixedArity<ExpressionIsoWeekYear, 1> {
public:
+ explicit ExpressionIsoWeekYear(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionIsoWeekYear, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -1353,6 +1585,9 @@ public:
class ExpressionIsoDayOfWeek final : public ExpressionFixedArity<ExpressionIsoDayOfWeek, 1> {
public:
+ explicit ExpressionIsoDayOfWeek(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionIsoDayOfWeek, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -1362,6 +1597,9 @@ public:
class ExpressionIsoWeek final : public ExpressionFixedArity<ExpressionIsoWeek, 1> {
public:
+ explicit ExpressionIsoWeek(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionIsoWeek, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -1371,6 +1609,9 @@ public:
class ExpressionYear final : public ExpressionFixedArity<ExpressionYear, 1> {
public:
+ explicit ExpressionYear(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : ExpressionFixedArity<ExpressionYear, 1>(expCtx) {}
+
Value evaluateInternal(Variables* vars) const final;
const char* getOpName() const final;
@@ -1383,15 +1624,18 @@ public:
class ExpressionZip final : public Expression {
public:
+ explicit ExpressionZip(const boost::intrusive_ptr<ExpressionContext>& expCtx)
+ : Expression(expCtx) {}
+
void addDependencies(DepsTracker* deps) const final;
Value evaluateInternal(Variables* vars) const final;
boost::intrusive_ptr<Expression> optimize() final;
- static boost::intrusive_ptr<Expression> parse(BSONElement expr,
- const VariablesParseState& vpsIn);
+ static boost::intrusive_ptr<Expression> parse(
+ const boost::intrusive_ptr<ExpressionContext>& expCtx,
+ BSONElement expr,
+ const VariablesParseState& vpsIn);
Value serialize(bool explain) const final;
- void doInjectExpressionContext() final;
-
private:
bool _useLongestLength = false;
ExpressionVector _inputs;