summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/expression.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/pipeline/expression.cpp')
-rw-r--r--src/mongo/db/pipeline/expression.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp
index 33d3c03c94e..016749ca29b 100644
--- a/src/mongo/db/pipeline/expression.cpp
+++ b/src/mongo/db/pipeline/expression.cpp
@@ -4781,6 +4781,17 @@ public:
};
//
+ // Conversions from String
+ //
+ table[BSONType::String][BSONType::NumberDouble] = &parseStringToNumber<double, 0>;
+ table[BSONType::String][BSONType::String] = &performIdentityConversion;
+ table[BSONType::String][BSONType::jstOID] = &parseStringToOID;
+ table[BSONType::String][BSONType::Bool] = [](Value inputValue) { return Value(true); };
+ table[BSONType::String][BSONType::NumberInt] = &parseStringToNumber<int, 10>;
+ table[BSONType::String][BSONType::NumberLong] = &parseStringToNumber<long long, 10>;
+ table[BSONType::String][BSONType::NumberDecimal] = &parseStringToNumber<Decimal128, 0>;
+
+ //
// Conversions from jstOID
//
table[BSONType::jstOID][BSONType::Date] = [](Value inputValue) {
@@ -5017,6 +5028,42 @@ private:
return Value(Date_t::fromMillisSinceEpoch(millisSinceEpoch));
}
+ template <class targetType, int base>
+ static Value parseStringToNumber(Value inputValue) {
+ auto stringValue = inputValue.getStringData();
+ targetType result;
+
+ // Reject any strings in hex format. This check is needed because the
+ // parseNumberFromStringWithBase call below allows an input hex string prefixed by '0x' when
+ // parsing to a double.
+ uassert(ErrorCodes::ConversionFailure,
+ str::stream() << "Illegal hexadecimal input in $convert with no onError value: "
+ << stringValue,
+ !stringValue.startsWith("0x"));
+
+ Status parseStatus = parseNumberFromStringWithBase(stringValue, base, &result);
+ uassert(ErrorCodes::ConversionFailure,
+ str::stream() << "Failed to parse number '" << stringValue
+ << "' in $convert with no onError value: "
+ << parseStatus.reason(),
+ parseStatus.isOK());
+
+ return Value(result);
+ }
+
+ static Value parseStringToOID(Value inputValue) {
+ try {
+ return Value(OID::createFromString(inputValue.getStringData()));
+ } catch (const DBException& ex) {
+ // Rethrow any caught exception as a conversion failure such that 'onError' is evaluated
+ // and returned.
+ uasserted(ErrorCodes::ConversionFailure,
+ str::stream() << "Failed to parse objectId '" << inputValue.getString()
+ << "' in $convert with no onError value: "
+ << ex.reason());
+ }
+ }
+
static Value performIdentityConversion(Value inputValue) {
return inputValue;
}