summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/expression.h
diff options
context:
space:
mode:
authorPatrick Meredith <pmeredit@gmail.com>2018-10-12 16:59:29 -0400
committerCharlie Swanson <charlie.swanson@mongodb.com>2018-12-22 21:20:56 -0500
commit43cd5d0e35df926eeaacec3f8d676bb5f6dd287b (patch)
tree42040670b45de7a3dcde2bf8c59f1f89cd4d01a3 /src/mongo/db/pipeline/expression.h
parent8195b17e78a2f0617289e1d8f3b318e1f2c8f077 (diff)
downloadmongo-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.h46
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)