diff options
author | Patrick Meredith <pmeredit@gmail.com> | 2018-10-12 16:59:29 -0400 |
---|---|---|
committer | Charlie Swanson <charlie.swanson@mongodb.com> | 2018-12-22 21:20:56 -0500 |
commit | 43cd5d0e35df926eeaacec3f8d676bb5f6dd287b (patch) | |
tree | 42040670b45de7a3dcde2bf8c59f1f89cd4d01a3 /src/mongo/db/pipeline/expression.h | |
parent | 8195b17e78a2f0617289e1d8f3b318e1f2c8f077 (diff) | |
download | mongo-43cd5d0e35df926eeaacec3f8d676bb5f6dd287b.tar.gz |
SERVER-32930 Add trigonometric expressions to aggregation
Closes #1287
Signed-off-by: Charlie Swanson <charlie.swanson@mongodb.com>
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) |