diff options
author | James Cohan <james.cohan@10gen.com> | 2015-08-04 13:28:16 -0400 |
---|---|---|
committer | James Cohan <james.cohan@10gen.com> | 2015-08-04 13:28:16 -0400 |
commit | 6ba08bc5bdcd4f41899a0fc7c8a60cbc3aed1102 (patch) | |
tree | d5f893abf6f5d8f7b28748c679df2afa7ea0b811 /src/mongo/db/pipeline | |
parent | cbfd06f789a99ab446da4f388f018c17225e02d2 (diff) | |
download | mongo-6ba08bc5bdcd4f41899a0fc7c8a60cbc3aed1102.tar.gz |
Revert "SERVER-18427 Adds $log, $log10, $ln, $pow, and $exp aggregation expressions"
This reverts commit f0541cc1f7f9cf1987aaf392dcb2328f71d6d232.
Diffstat (limited to 'src/mongo/db/pipeline')
-rw-r--r-- | src/mongo/db/pipeline/expression.cpp | 249 | ||||
-rw-r--r-- | src/mongo/db/pipeline/expression.h | 26 |
2 files changed, 0 insertions, 275 deletions
diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp index db3443362fe..88a471d0792 100644 --- a/src/mongo/db/pipeline/expression.cpp +++ b/src/mongo/db/pipeline/expression.cpp @@ -1154,26 +1154,6 @@ const char* ExpressionDivide::getOpName() const { return "$divide"; } -/* ----------------------- ExpressionExp ---------------------------- */ - -Value ExpressionExp::evaluateInternal(Variables* vars) const { - Value expVal = vpOperand[0]->evaluateInternal(vars); - if (expVal.nullish()) - return Value(BSONNULL); - - uassert(28765, - str::stream() << "$exp only supports numeric types, not " << typeName(expVal.getType()), - expVal.numeric()); - - // exp() always returns a double since e is a double. - return Value(exp(expVal.coerceToDouble())); -} - -REGISTER_EXPRESSION(exp, ExpressionExp::parse); -const char* ExpressionExp::getOpName() const { - return "$exp"; -} - /* ---------------------- ExpressionObject --------------------------- */ intrusive_ptr<ExpressionObject> ExpressionObject::create() { @@ -2073,85 +2053,6 @@ const char* ExpressionIfNull::getOpName() const { return "$ifNull"; } -/* ----------------------- ExpressionLn ---------------------------- */ - -Value ExpressionLn::evaluateInternal(Variables* vars) const { - Value argVal = vpOperand[0]->evaluateInternal(vars); - if (argVal.nullish()) - return Value(BSONNULL); - - uassert(28754, - str::stream() << "$ln only supports numeric types, not " << typeName(argVal.getType()), - argVal.numeric()); - - double argDouble = argVal.coerceToDouble(); - uassert(28755, - str::stream() << "$ln's argument must be a positive number, but is " << argDouble, - argDouble > 0 || std::isnan(argDouble)); - return Value(std::log(argDouble)); -} - -REGISTER_EXPRESSION(ln, ExpressionLn::parse); -const char* ExpressionLn::getOpName() const { - return "$ln"; -} - -/* ----------------------- ExpressionLog ---------------------------- */ - -Value ExpressionLog::evaluateInternal(Variables* vars) const { - Value argVal = vpOperand[0]->evaluateInternal(vars); - Value baseVal = vpOperand[1]->evaluateInternal(vars); - if (argVal.nullish() || baseVal.nullish()) - return Value(BSONNULL); - - uassert(28756, - str::stream() << "$log's argument must be numeric, not " << typeName(argVal.getType()), - argVal.numeric()); - uassert(28757, - str::stream() << "$log's base must be numeric, not " << typeName(baseVal.getType()), - baseVal.numeric()); - - double argDouble = argVal.coerceToDouble(); - double baseDouble = baseVal.coerceToDouble(); - uassert(28758, - str::stream() << "$log's argument must be a positive number, but is " << argDouble, - argDouble > 0 || std::isnan(argDouble)); - uassert(28759, - str::stream() << "$log's base must be a positive number not equal to 1, but is " - << baseDouble, - (baseDouble > 0 && baseDouble != 1) || std::isnan(baseDouble)); - return Value(std::log(argDouble) / std::log(baseDouble)); -} - -REGISTER_EXPRESSION(log, ExpressionLog::parse); -const char* ExpressionLog::getOpName() const { - return "$log"; -} - -/* ----------------------- ExpressionLog10 ---------------------------- */ - -Value ExpressionLog10::evaluateInternal(Variables* vars) const { - Value argVal = vpOperand[0]->evaluateInternal(vars); - if (argVal.nullish()) - return Value(BSONNULL); - - uassert(28760, - str::stream() << "$log10 only supports numeric types, not " - << typeName(argVal.getType()), - argVal.numeric()); - - double argDouble = argVal.coerceToDouble(); - uassert(28761, - str::stream() << "$log10's argument must be a positive number, but is " << argDouble, - argDouble > 0 || std::isnan(argDouble)); - return Value(std::log10(argDouble)); -} - -REGISTER_EXPRESSION(log10, ExpressionLog10::parse); -const char* ExpressionLog10::getOpName() const { - return "$log10"; -} - /* ------------------------ ExpressionNary ----------------------------- */ intrusive_ptr<Expression> ExpressionNary::optimize() { @@ -2327,156 +2228,6 @@ const char* ExpressionOr::getOpName() const { return "$or"; } -/* ----------------------- ExpressionPow ---------------------------- */ - -Value ExpressionPow::evaluateInternal(Variables* vars) const { - Value baseVal = vpOperand[0]->evaluateInternal(vars); - Value expVal = vpOperand[1]->evaluateInternal(vars); - if (baseVal.nullish() || expVal.nullish()) - return Value(BSONNULL); - - BSONType baseType = baseVal.getType(); - BSONType expType = expVal.getType(); - - uassert(28762, - str::stream() << "$pow's base must be numeric, not " << typeName(baseType), - baseVal.numeric()); - uassert(28763, - str::stream() << "$pow's exponent must be numeric, not " << typeName(expType), - expVal.numeric()); - - // pow() will cast args to doubles. - double baseNum = baseVal.coerceToDouble(); - double expNum = expVal.coerceToDouble(); - - uassert(28764, - "$pow cannot take a base of 0 and a negative exponent", - !(baseNum == 0 && expNum < 0)); - - // If either number is a double, return a double. - if (baseType == NumberDouble || expType == NumberDouble) { - return Value(pow(baseNum, expNum)); - } - - // base and exp are both integers. - - auto representableAsLong = [](long long base, long long exp) { - // If exp is greater than 63 and base is not -1, 0, or 1, the result will overflow. - // If exp is negative and the base is not -1 or 1, the result will be fractional. - if (exp < 0 || exp > 63) { - return std::abs(base) == 1 || base == 0; - } - - struct MinMax { - long long min; - long long max; - }; - - // Array indices correspond to exponents 0 through 63. The values in each index are the min - // and max bases, respectively, that can be raised to that exponent without overflowing a - // 64-bit int. For max bases, this was computed by solving for b in - // b = (2^63-1)^(1/exp) for exp = [0, 63] and truncating b. To calculate min bases, for even - // exps the equation used was b = (2^63-1)^(1/exp), and for odd exps the equation used was - // b = (-2^63)^(1/exp). Since the magnitude of long min is greater than long max, the - // magnitude of some of the min bases raised to odd exps is greater than the corresponding - // max bases raised to the same exponents. - - static const MinMax kBaseLimits[] = { - {std::numeric_limits<long long>::min(), std::numeric_limits<long long>::max()}, // 0 - {std::numeric_limits<long long>::min(), std::numeric_limits<long long>::max()}, - {-3037000499, 3037000499}, - {-2097152, 2097151}, - {-55108, 55108}, - {-6208, 6208}, - {-1448, 1448}, - {-512, 511}, - {-234, 234}, - {-128, 127}, - {-78, 78}, // 10 - {-52, 52}, - {-38, 38}, - {-28, 28}, - {-22, 22}, - {-18, 18}, - {-15, 15}, - {-13, 13}, - {-11, 11}, - {-9, 9}, - {-8, 8}, // 20 - {-8, 7}, - {-7, 7}, - {-6, 6}, - {-6, 6}, - {-5, 5}, - {-5, 5}, - {-5, 5}, - {-4, 4}, - {-4, 4}, - {-4, 4}, // 30 - {-4, 4}, - {-3, 3}, - {-3, 3}, - {-3, 3}, - {-3, 3}, - {-3, 3}, - {-3, 3}, - {-3, 3}, - {-3, 3}, - {-2, 2}, // 40 - {-2, 2}, - {-2, 2}, - {-2, 2}, - {-2, 2}, - {-2, 2}, - {-2, 2}, - {-2, 2}, - {-2, 2}, - {-2, 2}, - {-2, 2}, // 50 - {-2, 2}, - {-2, 2}, - {-2, 2}, - {-2, 2}, - {-2, 2}, - {-2, 2}, - {-2, 2}, - {-2, 2}, - {-2, 2}, - {-2, 2}, // 60 - {-2, 2}, - {-2, 2}, - {-2, 1}}; - - return base >= kBaseLimits[exp].min && base <= kBaseLimits[exp].max; - }; - - // If the result cannot be represented as a long, return a double. Otherwise if either number - // is a long, return a long. If both numbers are ints, then return an int if the result fits or - // a long if it is too big. - if (!representableAsLong(baseNum, expNum)) { - return Value(pow(baseNum, expNum)); - } - - long long baseLong = baseVal.getLong(); - long long expLong = expVal.getLong(); - long long result = 1; - // Use repeated multiplication, since pow() casts args to doubles which could result in loss of - // precision if arguments are very large. - for (int i = 0; i < expLong; i++) { - result *= baseLong; - } - - if (baseType == NumberLong || expType == NumberLong) { - return Value(result); - } - return Value::createIntOrLong(result); -} - -REGISTER_EXPRESSION(pow, ExpressionPow::parse); -const char* ExpressionPow::getOpName() const { - return "$pow"; -} - /* ------------------------- ExpressionSecond ----------------------------- */ Value ExpressionSecond::evaluateInternal(Variables* vars) const { diff --git a/src/mongo/db/pipeline/expression.h b/src/mongo/db/pipeline/expression.h index 5113c104686..b4caa27ae52 100644 --- a/src/mongo/db/pipeline/expression.h +++ b/src/mongo/db/pipeline/expression.h @@ -639,12 +639,6 @@ public: }; -class ExpressionExp final : public ExpressionFixedArity<ExpressionExp, 1> { - Value evaluateInternal(Variables* vars) const final; - const char* getOpName() const final; -}; - - class ExpressionFieldPath final : public Expression { public: boost::intrusive_ptr<Expression> optimize() final; @@ -772,21 +766,6 @@ private: boost::intrusive_ptr<Expression> _subExpression; }; -class ExpressionLn final : public ExpressionFixedArity<ExpressionLn, 1> { - Value evaluateInternal(Variables* vars) const final; - const char* getOpName() const final; -}; - -class ExpressionLog final : public ExpressionFixedArity<ExpressionLog, 2> { - Value evaluateInternal(Variables* vars) const final; - const char* getOpName() const final; -}; - -class ExpressionLog10 final : public ExpressionFixedArity<ExpressionLog10, 1> { - Value evaluateInternal(Variables* vars) const final; - const char* getOpName() const final; -}; - class ExpressionMap final : public Expression { public: boost::intrusive_ptr<Expression> optimize() final; @@ -1002,11 +981,6 @@ public: } }; -class ExpressionPow final : public ExpressionFixedArity<ExpressionPow, 2> { - Value evaluateInternal(Variables* vars) const final; - const char* getOpName() const final; -}; - class ExpressionSecond final : public ExpressionFixedArity<ExpressionSecond, 1> { public: |