summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/expression_trigonometric.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/pipeline/expression_trigonometric.h')
-rw-r--r--src/mongo/db/pipeline/expression_trigonometric.h38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/mongo/db/pipeline/expression_trigonometric.h b/src/mongo/db/pipeline/expression_trigonometric.h
index 1c4236e7ccc..b015f97da78 100644
--- a/src/mongo/db/pipeline/expression_trigonometric.h
+++ b/src/mongo/db/pipeline/expression_trigonometric.h
@@ -230,4 +230,42 @@ public:
*/
virtual const char* getOpName() const = 0;
};
+
+class ExpressionArcTangent2 final : public ExpressionTwoNumericArgs<ExpressionArcTangent2> {
+public:
+ explicit ExpressionArcTangent2(ExpressionContext* const expCtx)
+ : ExpressionTwoNumericArgs(expCtx) {}
+
+ ExpressionArcTangent2(ExpressionContext* const expCtx, ExpressionVector&& children)
+ : ExpressionTwoNumericArgs(expCtx, std::move(children)) {}
+
+ Value evaluateNumericArgs(const Value& numericArg1, const Value& numericArg2) const final {
+ auto totalType = BSONType::NumberDouble;
+ // If the type of either argument is NumberDecimal, we promote to Decimal128.
+ if (numericArg1.getType() == BSONType::NumberDecimal ||
+ numericArg2.getType() == BSONType::NumberDecimal) {
+ totalType = BSONType::NumberDecimal;
+ }
+ switch (totalType) {
+ case BSONType::NumberDecimal: {
+ auto dec = numericArg1.coerceToDecimal();
+ return Value(dec.atan2(numericArg2.coerceToDecimal()));
+ }
+ case BSONType::NumberDouble: {
+ return Value(
+ std::atan2(numericArg1.coerceToDouble(), numericArg2.coerceToDouble()));
+ }
+ default:
+ MONGO_UNREACHABLE;
+ }
+ }
+
+ const char* getOpName() const final {
+ return "$atan2";
+ }
+
+ void acceptVisitor(ExpressionVisitor* visitor) final {
+ return visitor->visit(this);
+ }
+};
} // namespace mongo