diff options
Diffstat (limited to 'src/mongo/db/pipeline/expression_trigonometric.h')
-rw-r--r-- | src/mongo/db/pipeline/expression_trigonometric.h | 38 |
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 |