summaryrefslogtreecommitdiff
path: root/src/mongo/base/parse_number.cpp
diff options
context:
space:
mode:
authorNick Zolnierz <nicholas.zolnierz@mongodb.com>2018-02-16 11:21:58 -0500
committerNick Zolnierz <nicholas.zolnierz@mongodb.com>2018-02-26 10:18:07 -0500
commit35212ca1250977a64f190a8de3572a35a88343c6 (patch)
tree0a4fcd84069bd288b6e006a6b9c1a2096b08c013 /src/mongo/base/parse_number.cpp
parentbebdcf721eaa24fa589977bf48459a8cdd0fb2a2 (diff)
downloadmongo-35212ca1250977a64f190a8de3572a35a88343c6.tar.gz
SERVER-33171: Add number and objectID parsing conversions to $convert
Diffstat (limited to 'src/mongo/base/parse_number.cpp')
-rw-r--r--src/mongo/base/parse_number.cpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/mongo/base/parse_number.cpp b/src/mongo/base/parse_number.cpp
index c7f7258ac5c..372ebb4aaf9 100644
--- a/src/mongo/base/parse_number.cpp
+++ b/src/mongo/base/parse_number.cpp
@@ -37,6 +37,7 @@
#include <string>
#include "mongo/base/status_with.h"
+#include "mongo/platform/decimal128.h"
#include "mongo/platform/overflow_arithmetic.h"
namespace mongo {
@@ -260,4 +261,35 @@ Status parseNumberFromStringWithBase<double>(StringData stringValue, int base, d
return Status::OK();
}
+template <>
+Status parseNumberFromStringWithBase<Decimal128>(StringData stringValue,
+ int base,
+ Decimal128* result) {
+ if (base != 0) {
+ return Status(ErrorCodes::BadValue,
+ "Must pass 0 as base to parseNumberFromStringWithBase<Decimal128>.");
+ }
+
+ if (stringValue.empty()) {
+ return Status(ErrorCodes::FailedToParse, "Empty string");
+ }
+
+ std::uint32_t signalingFlags = 0;
+ auto parsedDecimal = Decimal128(
+ stringValue.toString(), &signalingFlags, Decimal128::RoundingMode::kRoundTowardZero);
+
+ if (Decimal128::hasFlag(signalingFlags, Decimal128::SignalingFlag::kOverflow)) {
+ return Status(ErrorCodes::FailedToParse,
+ "Conversion from string to decimal would overflow");
+ } else if (Decimal128::hasFlag(signalingFlags, Decimal128::SignalingFlag::kUnderflow)) {
+ return Status(ErrorCodes::FailedToParse,
+ "Conversion from string to decimal would underflow");
+ } else if (signalingFlags != Decimal128::SignalingFlag::kNoFlag &&
+ signalingFlags != Decimal128::SignalingFlag::kInexact) { // Ignore precision loss.
+ return Status(ErrorCodes::FailedToParse, "Failed to parse string to decimal");
+ }
+
+ *result = parsedDecimal;
+ return Status::OK();
+}
} // namespace mongo