diff options
author | Nick Zolnierz <nicholas.zolnierz@mongodb.com> | 2018-02-16 11:21:58 -0500 |
---|---|---|
committer | Nick Zolnierz <nicholas.zolnierz@mongodb.com> | 2018-02-26 10:18:07 -0500 |
commit | 35212ca1250977a64f190a8de3572a35a88343c6 (patch) | |
tree | 0a4fcd84069bd288b6e006a6b9c1a2096b08c013 /src/mongo/db/pipeline/expression.cpp | |
parent | bebdcf721eaa24fa589977bf48459a8cdd0fb2a2 (diff) | |
download | mongo-35212ca1250977a64f190a8de3572a35a88343c6.tar.gz |
SERVER-33171: Add number and objectID parsing conversions to $convert
Diffstat (limited to 'src/mongo/db/pipeline/expression.cpp')
-rw-r--r-- | src/mongo/db/pipeline/expression.cpp | 47 |
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; } |