diff options
Diffstat (limited to 'src/mongo/db/pipeline/expression.h')
-rw-r--r-- | src/mongo/db/pipeline/expression.h | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/src/mongo/db/pipeline/expression.h b/src/mongo/db/pipeline/expression.h index 82e8f245be0..31d1e185d34 100644 --- a/src/mongo/db/pipeline/expression.h +++ b/src/mongo/db/pipeline/expression.h @@ -435,7 +435,7 @@ public: explicit ExpressionSingleNumericArg(const boost::intrusive_ptr<ExpressionContext>& expCtx) : ExpressionFixedArity<SubClass, 1>(expCtx) {} - virtual ~ExpressionSingleNumericArg() {} + virtual ~ExpressionSingleNumericArg() = default; Value evaluate(const Document& root) const final { Value arg = this->vpOperand[0]->evaluate(root); @@ -454,6 +454,49 @@ public: }; /** + * Inherit from this class if your expression takes exactly two numeric arguments. + */ +template <typename SubClass> +class ExpressionTwoNumericArgs : public ExpressionFixedArity<SubClass, 2> { +public: + explicit ExpressionTwoNumericArgs(const boost::intrusive_ptr<ExpressionContext>& expCtx) + : ExpressionFixedArity<SubClass, 2>(expCtx) {} + + virtual ~ExpressionTwoNumericArgs() = default; + + /** + * Evaluate performs the type checking necessary to make sure that both arguments are numeric, + * then calls the evaluateNumericArgs on the two numeric args: + * 1. If either input is nullish, it returns null. + * 2. If either input is not numeric, it throws an error. + * 3. Call evaluateNumericArgs on the two numeric args. + */ + Value evaluate(const Document& root) const final { + Value arg1 = this->vpOperand[0]->evaluate(root); + if (arg1.nullish()) + return Value(BSONNULL); + uassert(51044, + str::stream() << this->getOpName() << " only supports numeric types, not " + << typeName(arg1.getType()), + arg1.numeric()); + Value arg2 = this->vpOperand[1]->evaluate(root); + if (arg2.nullish()) + return Value(BSONNULL); + uassert(51045, + str::stream() << this->getOpName() << " only supports numeric types, not " + << typeName(arg2.getType()), + arg2.numeric()); + + return evaluateNumericArgs(arg1, arg2); + } + + /** + * Evaluate the expression on exactly two numeric arguments. + */ + virtual Value evaluateNumericArgs(const Value& numericArg1, const Value& numericArg2) const = 0; +}; + +/** * A constant expression. Repeated calls to evaluate() will always return the same thing. */ class ExpressionConstant final : public Expression { @@ -665,7 +708,6 @@ public: const char* getOpName() const final; }; - class ExpressionAdd final : public ExpressionVariadic<ExpressionAdd> { public: explicit ExpressionAdd(const boost::intrusive_ptr<ExpressionContext>& expCtx) |