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.cpp281
1 files changed, 113 insertions, 168 deletions
diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp
index 0c0ef86f963..e8b758356d9 100644
--- a/src/mongo/db/pipeline/expression.cpp
+++ b/src/mongo/db/pipeline/expression.cpp
@@ -112,7 +112,7 @@ struct ParserRegistration {
};
StringMap<ParserRegistration> parserMap;
-}
+} // namespace
void Expression::registerExpression(
string key,
@@ -145,17 +145,16 @@ intrusive_ptr<Expression> Expression::parseExpression(
// Make sure we are allowed to use this expression under the current feature compatibility
// version.
auto& entry = it->second;
- uassert(
- ErrorCodes::QueryFeatureNotAllowed,
- // TODO SERVER-31968 we would like to include the current version and the required minimum
- // version in this error message, but using FeatureCompatibilityVersion::toString() would
- // introduce a dependency cycle.
- str::stream() << opName
- << " is not allowed in the current feature compatibility version. See "
- << feature_compatibility_version_documentation::kCompatibilityLink
- << " for more information.",
- !expCtx->maxFeatureCompatibilityVersion || !entry.requiredMinVersion ||
- (*entry.requiredMinVersion <= *expCtx->maxFeatureCompatibilityVersion));
+ uassert(ErrorCodes::QueryFeatureNotAllowed,
+ // TODO SERVER-31968 we would like to include the current version and the required
+ // minimum version in this error message, but using
+ // FeatureCompatibilityVersion::toString() would introduce a dependency cycle.
+ str::stream() << opName
+ << " is not allowed in the current feature compatibility version. See "
+ << feature_compatibility_version_documentation::kCompatibilityLink
+ << " for more information.",
+ !expCtx->maxFeatureCompatibilityVersion || !entry.requiredMinVersion ||
+ (*entry.requiredMinVersion <= *expCtx->maxFeatureCompatibilityVersion));
return entry.parser(expCtx, obj.firstElement(), vps);
}
@@ -522,13 +521,11 @@ Value ExpressionArrayElemAt::evaluate(const Document& root, Variables* variables
array.isArray());
uassert(28690,
str::stream() << getOpName() << "'s second argument must be a numeric value,"
- << " but is "
- << typeName(indexArg.getType()),
+ << " but is " << typeName(indexArg.getType()),
indexArg.numeric());
uassert(28691,
str::stream() << getOpName() << "'s second argument must be representable as"
- << " a 32-bit integer: "
- << indexArg.coerceToDouble(),
+ << " a 32-bit integer: " << indexArg.coerceToDouble(),
indexArg.integral());
long long i = indexArg.coerceToLong();
@@ -808,7 +805,7 @@ static const CmpLookup cmpLookup[7] = {
// CMP is special. Only name is used.
/* CMP */ {{false, false, false}, ExpressionCompare::CMP, "$cmp"},
};
-}
+} // namespace
Value ExpressionCompare::evaluate(const Document& root, Variables* variables) const {
Value pLeft(_children[0]->evaluate(root, variables));
@@ -1063,8 +1060,8 @@ intrusive_ptr<Expression> ExpressionDateFromParts::parse(
timeZoneElem = arg;
} else {
uasserted(40518,
- str::stream() << "Unrecognized argument to $dateFromParts: "
- << arg.fieldName());
+ str::stream()
+ << "Unrecognized argument to $dateFromParts: " << arg.fieldName());
}
}
@@ -1222,8 +1219,7 @@ bool ExpressionDateFromParts::evaluateNumberWithDefault(const Document& root,
uassert(40515,
str::stream() << "'" << fieldName << "' must evaluate to an integer, found "
- << typeName(fieldValue.getType())
- << " with value "
+ << typeName(fieldValue.getType()) << " with value "
<< fieldValue.toString(),
fieldValue.integral64Bit());
@@ -1241,17 +1237,12 @@ bool ExpressionDateFromParts::evaluateNumberWithDefaultAndBounds(const Document&
bool result =
evaluateNumberWithDefault(root, field, fieldName, defaultValue, returnValue, variables);
- uassert(31034,
- str::stream() << "'" << fieldName << "'"
- << " must evaluate to a value in the range ["
- << kMinValueForDatePart
- << ", "
- << kMaxValueForDatePart
- << "]; value "
- << *returnValue
- << " is not in range",
- !result ||
- (*returnValue >= kMinValueForDatePart && *returnValue <= kMaxValueForDatePart));
+ uassert(
+ 31034,
+ str::stream() << "'" << fieldName << "'"
+ << " must evaluate to a value in the range [" << kMinValueForDatePart << ", "
+ << kMaxValueForDatePart << "]; value " << *returnValue << " is not in range",
+ !result || (*returnValue >= kMinValueForDatePart && *returnValue <= kMaxValueForDatePart));
return result;
}
@@ -1289,9 +1280,7 @@ Value ExpressionDateFromParts::evaluate(const Document& root, Variables* variabl
uassert(40523,
str::stream() << "'year' must evaluate to an integer in the range " << 0 << " to "
- << 9999
- << ", found "
- << year,
+ << 9999 << ", found " << year,
year >= 0 && year <= 9999);
return Value(
@@ -1313,10 +1302,7 @@ Value ExpressionDateFromParts::evaluate(const Document& root, Variables* variabl
uassert(31095,
str::stream() << "'isoWeekYear' must evaluate to an integer in the range " << 0
- << " to "
- << 9999
- << ", found "
- << isoWeekYear,
+ << " to " << 9999 << ", found " << isoWeekYear,
isoWeekYear >= 0 && isoWeekYear <= 9999);
return Value(timeZone->createFromIso8601DateParts(
@@ -1393,8 +1379,8 @@ intrusive_ptr<Expression> ExpressionDateFromString::parse(
onErrorElem = arg;
} else {
uasserted(40541,
- str::stream() << "Unrecognized argument to $dateFromString: "
- << arg.fieldName());
+ str::stream()
+ << "Unrecognized argument to $dateFromString: " << arg.fieldName());
}
}
@@ -1476,8 +1462,7 @@ Value ExpressionDateFromString::evaluate(const Document& root, Variables* variab
if (!formatValue.nullish()) {
uassert(40684,
str::stream() << "$dateFromString requires that 'format' be a string, found: "
- << typeName(formatValue.getType())
- << " with value "
+ << typeName(formatValue.getType()) << " with value "
<< formatValue.toString(),
formatValue.getType() == BSONType::String);
@@ -1498,8 +1483,7 @@ Value ExpressionDateFromString::evaluate(const Document& root, Variables* variab
try {
uassert(ErrorCodes::ConversionFailure,
str::stream() << "$dateFromString requires that 'dateString' be a string, found: "
- << typeName(dateString.getType())
- << " with value "
+ << typeName(dateString.getType()) << " with value "
<< dateString.toString(),
dateString.getType() == BSONType::String);
@@ -1575,8 +1559,8 @@ intrusive_ptr<Expression> ExpressionDateToParts::parse(
isoDateElem = arg;
} else {
uasserted(40520,
- str::stream() << "Unrecognized argument to $dateToParts: "
- << arg.fieldName());
+ str::stream()
+ << "Unrecognized argument to $dateToParts: " << arg.fieldName());
}
}
@@ -1723,8 +1707,8 @@ intrusive_ptr<Expression> ExpressionDateToString::parse(
onNullElem = arg;
} else {
uasserted(18534,
- str::stream() << "Unrecognized argument to $dateToString: "
- << arg.fieldName());
+ str::stream()
+ << "Unrecognized argument to $dateToString: " << arg.fieldName());
}
}
@@ -1794,8 +1778,7 @@ Value ExpressionDateToString::evaluate(const Document& root, Variables* variable
if (!formatValue.nullish()) {
uassert(18533,
str::stream() << "$dateToString requires that 'format' be a string, found: "
- << typeName(formatValue.getType())
- << " with value "
+ << typeName(formatValue.getType()) << " with value "
<< formatValue.toString(),
formatValue.getType() == BSONType::String);
@@ -1869,9 +1852,7 @@ Value ExpressionDivide::evaluate(const Document& root, Variables* variables) con
} else {
uasserted(16609,
str::stream() << "$divide only supports numeric types, not "
- << typeName(lhs.getType())
- << " and "
- << typeName(rhs.getType()));
+ << typeName(lhs.getType()) << " and " << typeName(rhs.getType()));
}
}
@@ -2234,9 +2215,8 @@ intrusive_ptr<Expression> ExpressionFilter::optimize() {
}
Value ExpressionFilter::serialize(bool explain) const {
- return Value(
- DOC("$filter" << DOC("input" << _input->serialize(explain) << "as" << _varName << "cond"
- << _filter->serialize(explain))));
+ return Value(DOC("$filter" << DOC("input" << _input->serialize(explain) << "as" << _varName
+ << "cond" << _filter->serialize(explain))));
}
Value ExpressionFilter::evaluate(const Document& root, Variables* variables) const {
@@ -2654,9 +2634,7 @@ Value ExpressionMod::evaluate(const Document& root, Variables* variables) const
} else {
uasserted(16611,
str::stream() << "$mod only supports numeric types, not "
- << typeName(lhs.getType())
- << " and "
- << typeName(rhs.getType()));
+ << typeName(lhs.getType()) << " and " << typeName(rhs.getType()));
}
}
@@ -2776,15 +2754,12 @@ void uassertIfNotIntegralAndNonNegative(Value val,
StringData argumentName) {
uassert(40096,
str::stream() << expressionName << "requires an integral " << argumentName
- << ", found a value of type: "
- << typeName(val.getType())
- << ", with value: "
- << val.toString(),
+ << ", found a value of type: " << typeName(val.getType())
+ << ", with value: " << val.toString(),
val.integral());
uassert(40097,
str::stream() << expressionName << " requires a nonnegative " << argumentName
- << ", found: "
- << val.toString(),
+ << ", found: " << val.toString(),
val.coerceToInt() >= 0);
}
@@ -2894,8 +2869,7 @@ intrusive_ptr<Expression> ExpressionIndexOfArray::optimize() {
}
uassert(50809,
str::stream() << "First operand of $indexOfArray must be an array. First "
- << "argument is of type: "
- << typeName(valueArray.getType()),
+ << "argument is of type: " << typeName(valueArray.getType()),
valueArray.isArray());
auto arr = valueArray.getArray();
@@ -3451,7 +3425,7 @@ bool representableAsLong(long long base, long long exp) {
return base >= kBaseLimits[exp].min && base <= kBaseLimits[exp].max;
};
-}
+} // namespace
/* ----------------------- ExpressionPow ---------------------------- */
@@ -3765,7 +3739,7 @@ ValueSet arrayToSet(const Value& val, const ValueComparator& valueComparator) {
valueSet.insert(array.begin(), array.end());
return valueSet;
}
-}
+} // namespace
/* ----------------------- ExpressionSetDifference ---------------------------- */
@@ -3779,13 +3753,11 @@ Value ExpressionSetDifference::evaluate(const Document& root, Variables* variabl
uassert(17048,
str::stream() << "both operands of $setDifference must be arrays. First "
- << "argument is of type: "
- << typeName(lhs.getType()),
+ << "argument is of type: " << typeName(lhs.getType()),
lhs.isArray());
uassert(17049,
str::stream() << "both operands of $setDifference must be arrays. Second "
- << "argument is of type: "
- << typeName(rhs.getType()),
+ << "argument is of type: " << typeName(rhs.getType()),
rhs.isArray());
ValueSet rhsSet = arrayToSet(rhs, getExpressionContext()->getValueComparator());
@@ -3824,8 +3796,7 @@ Value ExpressionSetEquals::evaluate(const Document& root, Variables* variables)
const Value nextEntry = _children[i]->evaluate(root, variables);
uassert(17044,
str::stream() << "All operands of $setEquals must be arrays. One "
- << "argument is of type: "
- << typeName(nextEntry.getType()),
+ << "argument is of type: " << typeName(nextEntry.getType()),
nextEntry.isArray());
if (i == 0) {
@@ -3863,8 +3834,7 @@ Value ExpressionSetIntersection::evaluate(const Document& root, Variables* varia
}
uassert(17047,
str::stream() << "All operands of $setIntersection must be arrays. One "
- << "argument is of type: "
- << typeName(nextEntry.getType()),
+ << "argument is of type: " << typeName(nextEntry.getType()),
nextEntry.isArray());
if (i == 0) {
@@ -3908,7 +3878,7 @@ Value setIsSubsetHelper(const vector<Value>& lhs, const ValueSet& rhs) {
}
return Value(true);
}
-}
+} // namespace
Value ExpressionSetIsSubset::evaluate(const Document& root, Variables* variables) const {
const Value lhs = _children[0]->evaluate(root, variables);
@@ -3916,13 +3886,11 @@ Value ExpressionSetIsSubset::evaluate(const Document& root, Variables* variables
uassert(17046,
str::stream() << "both operands of $setIsSubset must be arrays. First "
- << "argument is of type: "
- << typeName(lhs.getType()),
+ << "argument is of type: " << typeName(lhs.getType()),
lhs.isArray());
uassert(17042,
str::stream() << "both operands of $setIsSubset must be arrays. Second "
- << "argument is of type: "
- << typeName(rhs.getType()),
+ << "argument is of type: " << typeName(rhs.getType()),
rhs.isArray());
return setIsSubsetHelper(lhs.getArray(),
@@ -3950,8 +3918,7 @@ public:
uassert(17310,
str::stream() << "both operands of $setIsSubset must be arrays. First "
- << "argument is of type: "
- << typeName(lhs.getType()),
+ << "argument is of type: " << typeName(lhs.getType()),
lhs.isArray());
return setIsSubsetHelper(lhs.getArray(), _cachedRhsSet);
@@ -3973,8 +3940,7 @@ intrusive_ptr<Expression> ExpressionSetIsSubset::optimize() {
const Value rhs = ec->getValue();
uassert(17311,
str::stream() << "both operands of $setIsSubset must be arrays. Second "
- << "argument is of type: "
- << typeName(rhs.getType()),
+ << "argument is of type: " << typeName(rhs.getType()),
rhs.isArray());
intrusive_ptr<Expression> optimizedWithConstant(
@@ -4003,8 +3969,7 @@ Value ExpressionSetUnion::evaluate(const Document& root, Variables* variables) c
}
uassert(17043,
str::stream() << "All operands of $setUnion must be arrays. One argument"
- << " is of type: "
- << typeName(newEntries.getType()),
+ << " is of type: " << typeName(newEntries.getType()),
newEntries.isArray());
unionedSet.insert(newEntries.getArray().begin(), newEntries.getArray().end());
@@ -4044,18 +4009,15 @@ Value ExpressionSlice::evaluate(const Document& root, Variables* variables) cons
uassert(28724,
str::stream() << "First argument to $slice must be an array, but is"
- << " of type: "
- << typeName(arrayVal.getType()),
+ << " of type: " << typeName(arrayVal.getType()),
arrayVal.isArray());
uassert(28725,
str::stream() << "Second argument to $slice must be a numeric value,"
- << " but is of type: "
- << typeName(arg2.getType()),
+ << " but is of type: " << typeName(arg2.getType()),
arg2.numeric());
uassert(28726,
str::stream() << "Second argument to $slice can't be represented as"
- << " a 32-bit integer: "
- << arg2.coerceToDouble(),
+ << " a 32-bit integer: " << arg2.coerceToDouble(),
arg2.integral());
const auto& array = arrayVal.getArray();
@@ -4095,13 +4057,11 @@ Value ExpressionSlice::evaluate(const Document& root, Variables* variables) cons
uassert(28727,
str::stream() << "Third argument to $slice must be numeric, but "
- << "is of type: "
- << typeName(countVal.getType()),
+ << "is of type: " << typeName(countVal.getType()),
countVal.numeric());
uassert(28728,
str::stream() << "Third argument to $slice can't be represented"
- << " as a 32-bit integer: "
- << countVal.coerceToDouble(),
+ << " as a 32-bit integer: " << countVal.coerceToDouble(),
countVal.integral());
uassert(28729,
str::stream() << "Third argument to $slice must be positive: "
@@ -4250,23 +4210,20 @@ Value ExpressionSubstrBytes::evaluate(const Document& root, Variables* variables
uassert(16034,
str::stream() << getOpName()
<< ": starting index must be a numeric type (is BSON type "
- << typeName(pLower.getType())
- << ")",
+ << typeName(pLower.getType()) << ")",
(pLower.getType() == NumberInt || pLower.getType() == NumberLong ||
pLower.getType() == NumberDouble));
uassert(16035,
str::stream() << getOpName() << ": length must be a numeric type (is BSON type "
- << typeName(pLength.getType())
- << ")",
+ << typeName(pLength.getType()) << ")",
(pLength.getType() == NumberInt || pLength.getType() == NumberLong ||
pLength.getType() == NumberDouble));
const long long signedLower = pLower.coerceToLong();
uassert(50752,
- str::stream() << getOpName() << ": starting index must be non-negative (got: "
- << signedLower
- << ")",
+ str::stream() << getOpName()
+ << ": starting index must be non-negative (got: " << signedLower << ")",
signedLower >= 0);
const string::size_type lower = static_cast<string::size_type>(signedLower);
@@ -4314,8 +4271,7 @@ Value ExpressionSubstrCP::evaluate(const Document& root, Variables* variables) c
std::string str = inputVal.coerceToString();
uassert(34450,
str::stream() << getOpName() << ": starting index must be a numeric type (is BSON type "
- << typeName(lowerVal.getType())
- << ")",
+ << typeName(lowerVal.getType()) << ")",
lowerVal.numeric());
uassert(34451,
str::stream() << getOpName()
@@ -4324,8 +4280,7 @@ Value ExpressionSubstrCP::evaluate(const Document& root, Variables* variables) c
lowerVal.integral());
uassert(34452,
str::stream() << getOpName() << ": length must be a numeric type (is BSON type "
- << typeName(lengthVal.getType())
- << ")",
+ << typeName(lengthVal.getType()) << ")",
lengthVal.numeric());
uassert(34453,
str::stream() << getOpName()
@@ -4460,8 +4415,8 @@ Value ExpressionSubtract::evaluate(const Document& root, Variables* variables) c
return Value(lhs.getDate() - Milliseconds(rhs.coerceToLong()));
} else {
uasserted(16613,
- str::stream() << "cant $subtract a " << typeName(rhs.getType())
- << " from a Date");
+ str::stream()
+ << "cant $subtract a " << typeName(rhs.getType()) << " from a Date");
}
} else {
uasserted(16556,
@@ -4587,7 +4542,7 @@ boost::intrusive_ptr<Expression> ExpressionSwitch::optimize() {
_default = _default->optimize();
}
- for (auto && [ switchCase, switchThen ] : _branches) {
+ for (auto&& [switchCase, switchThen] : _branches) {
switchCase = switchCase->optimize();
switchThen = switchThen->optimize();
}
@@ -4744,8 +4699,7 @@ std::vector<StringData> extractCodePointsFromChars(StringData utf8String,
}
uassert(50697,
str::stream()
- << "Failed to parse \"chars\" argument to "
- << expressionName
+ << "Failed to parse \"chars\" argument to " << expressionName
<< ": Detected invalid UTF-8. Missing expected continuation byte at end of string.",
i <= utf8String.size());
return codePoints;
@@ -4759,10 +4713,8 @@ Value ExpressionTrim::evaluate(const Document& root, Variables* variables) const
}
uassert(50699,
str::stream() << _name << " requires its input to be a string, got "
- << unvalidatedInput.toString()
- << " (of type "
- << typeName(unvalidatedInput.getType())
- << ") instead.",
+ << unvalidatedInput.toString() << " (of type "
+ << typeName(unvalidatedInput.getType()) << ") instead.",
unvalidatedInput.getType() == BSONType::String);
const StringData input(unvalidatedInput.getStringData());
@@ -4775,10 +4727,8 @@ Value ExpressionTrim::evaluate(const Document& root, Variables* variables) const
}
uassert(50700,
str::stream() << _name << " requires 'chars' to be a string, got "
- << unvalidatedUserChars.toString()
- << " (of type "
- << typeName(unvalidatedUserChars.getType())
- << ") instead.",
+ << unvalidatedUserChars.toString() << " (of type "
+ << typeName(unvalidatedUserChars.getType()) << ") instead.",
unvalidatedUserChars.getType() == BSONType::String);
return Value(
@@ -4877,11 +4827,8 @@ void assertFlagsValid(uint32_t flags,
long long precisionValue) {
uassert(51080,
str::stream() << "invalid conversion from Decimal128 result in " << opName
- << " resulting from arguments: ["
- << numericValue
- << ", "
- << precisionValue
- << "]",
+ << " resulting from arguments: [" << numericValue << ", "
+ << precisionValue << "]",
!Decimal128::hasFlag(flags, Decimal128::kInvalid));
}
@@ -4914,8 +4861,7 @@ static Value evaluateRoundOrTrunc(const Document& root,
precisionArg.integral());
uassert(51083,
str::stream() << "cannot apply " << opName << " with precision value "
- << precisionValue
- << " value must be in [-20, 100]",
+ << precisionValue << " value must be in [-20, 100]",
minPrecision <= precisionValue && precisionValue <= maxPrecision);
}
@@ -5163,8 +5109,7 @@ Value ExpressionZip::serialize(bool explain) const {
}
return Value(DOC("$zip" << DOC("inputs" << Value(serializedInput) << "defaults"
- << Value(serializedDefaults)
- << "useLongestLength"
+ << Value(serializedDefaults) << "useLongestLength"
<< serializedUseLongestLength)));
}
@@ -5199,9 +5144,10 @@ public:
//
table[BSONType::NumberDouble][BSONType::NumberDouble] = &performIdentityConversion;
table[BSONType::NumberDouble][BSONType::String] = &performFormatDouble;
- table[BSONType::NumberDouble]
- [BSONType::Bool] = [](const boost::intrusive_ptr<ExpressionContext>& expCtx,
- Value inputValue) { return Value(inputValue.coerceToBool()); };
+ table[BSONType::NumberDouble][BSONType::Bool] =
+ [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
+ return Value(inputValue.coerceToBool());
+ };
table[BSONType::NumberDouble][BSONType::Date] = &performCastNumberToDate;
table[BSONType::NumberDouble][BSONType::NumberInt] = &performCastDoubleToInt;
table[BSONType::NumberDouble][BSONType::NumberLong] = &performCastDoubleToLong;
@@ -5217,11 +5163,11 @@ public:
table[BSONType::String][BSONType::String] = &performIdentityConversion;
table[BSONType::String][BSONType::jstOID] = &parseStringToOID;
table[BSONType::String][BSONType::Bool] = &performConvertToTrue;
- table[BSONType::String][BSONType::Date] = [](
- const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
- return Value(expCtx->timeZoneDatabase->fromString(inputValue.getStringData(),
- mongo::TimeZoneDatabase::utcZone()));
- };
+ table[BSONType::String][BSONType::Date] =
+ [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
+ return Value(expCtx->timeZoneDatabase->fromString(
+ inputValue.getStringData(), mongo::TimeZoneDatabase::utcZone()));
+ };
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>;
@@ -5278,9 +5224,10 @@ public:
inputValue.getDate());
return Value(dateString);
};
- table[BSONType::Date]
- [BSONType::Bool] = [](const boost::intrusive_ptr<ExpressionContext>& expCtx,
- Value inputValue) { return Value(inputValue.coerceToBool()); };
+ table[BSONType::Date][BSONType::Bool] =
+ [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
+ return Value(inputValue.coerceToBool());
+ };
table[BSONType::Date][BSONType::Date] = &performIdentityConversion;
table[BSONType::Date][BSONType::NumberLong] =
[](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
@@ -5303,9 +5250,10 @@ public:
[](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
return Value(static_cast<std::string>(str::stream() << inputValue.getInt()));
};
- table[BSONType::NumberInt]
- [BSONType::Bool] = [](const boost::intrusive_ptr<ExpressionContext>& expCtx,
- Value inputValue) { return Value(inputValue.coerceToBool()); };
+ table[BSONType::NumberInt][BSONType::Bool] =
+ [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
+ return Value(inputValue.coerceToBool());
+ };
table[BSONType::NumberInt][BSONType::NumberInt] = &performIdentityConversion;
table[BSONType::NumberInt][BSONType::NumberLong] =
[](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
@@ -5327,9 +5275,10 @@ public:
[](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
return Value(static_cast<std::string>(str::stream() << inputValue.getLong()));
};
- table[BSONType::NumberLong]
- [BSONType::Bool] = [](const boost::intrusive_ptr<ExpressionContext>& expCtx,
- Value inputValue) { return Value(inputValue.coerceToBool()); };
+ table[BSONType::NumberLong][BSONType::Bool] =
+ [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
+ return Value(inputValue.coerceToBool());
+ };
table[BSONType::NumberLong][BSONType::Date] = &performCastNumberToDate;
table[BSONType::NumberLong][BSONType::NumberInt] = &performCastLongToInt;
table[BSONType::NumberLong][BSONType::NumberLong] = &performIdentityConversion;
@@ -5346,9 +5295,10 @@ public:
[](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
return Value(inputValue.getDecimal().toString());
};
- table[BSONType::NumberDecimal]
- [BSONType::Bool] = [](const boost::intrusive_ptr<ExpressionContext>& expCtx,
- Value inputValue) { return Value(inputValue.coerceToBool()); };
+ table[BSONType::NumberDecimal][BSONType::Bool] =
+ [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
+ return Value(inputValue.coerceToBool());
+ };
table[BSONType::NumberDecimal][BSONType::Date] = &performCastNumberToDate;
table[BSONType::NumberDecimal][BSONType::NumberInt] =
[](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
@@ -5395,8 +5345,7 @@ public:
uassert(ErrorCodes::ConversionFailure,
str::stream() << "Unsupported conversion from " << typeName(inputType) << " to "
- << typeName(targetType)
- << " in $convert with no onError value",
+ << typeName(targetType) << " in $convert with no onError value",
foundFunction);
return foundFunction;
}
@@ -5570,8 +5519,7 @@ private:
Status parseStatus = NumberParser().base(base)(stringValue, &result);
uassert(ErrorCodes::ConversionFailure,
str::stream() << "Failed to parse number '" << stringValue
- << "' in $convert with no onError value: "
- << parseStatus.reason(),
+ << "' in $convert with no onError value: " << parseStatus.reason(),
parseStatus.isOK());
return Value(result);
@@ -5586,8 +5534,7 @@ private:
// and returned.
uasserted(ErrorCodes::ConversionFailure,
str::stream() << "Failed to parse objectId '" << inputValue.getString()
- << "' in $convert with no onError value: "
- << ex.reason());
+ << "' in $convert with no onError value: " << ex.reason());
}
}
@@ -5606,7 +5553,6 @@ Expression::Parser makeConversionAlias(const StringData shortcutName, BSONType t
return [=](const intrusive_ptr<ExpressionContext>& expCtx,
BSONElement elem,
const VariablesParseState& vps) -> intrusive_ptr<Expression> {
-
// Use parseArguments to allow for a singleton array, or the unwrapped version.
auto operands = ExpressionNary::parseArguments(expCtx, elem, vps);
@@ -5681,8 +5627,8 @@ intrusive_ptr<Expression> ExpressionConvert::parse(
onNull = parseOperand(expCtx, elem, vps);
} else {
uasserted(ErrorCodes::FailedToParse,
- str::stream() << "$convert found an unknown argument: "
- << elem.fieldNameStringData());
+ str::stream()
+ << "$convert found an unknown argument: " << elem.fieldNameStringData());
}
}
@@ -5808,8 +5754,8 @@ auto CommonRegexParse(const boost::intrusive_ptr<ExpressionContext>& expCtx,
const VariablesParseState& vpsIn,
StringData opName) {
uassert(51103,
- str::stream() << opName << " expects an object of named arguments but found: "
- << expr.type(),
+ str::stream() << opName
+ << " expects an object of named arguments but found: " << expr.type(),
expr.type() == BSONType::Object);
struct {
@@ -5881,8 +5827,7 @@ int ExpressionRegex::execute(RegexExecutionState* regexState) const {
// capacity is not sufficient to hold all the results. The latter scenario should never occur.
uassert(51156,
str::stream() << "Error occurred while executing the regular expression in " << _opName
- << ". Result code: "
- << execResult,
+ << ". Result code: " << execResult,
execResult == -1 || execResult == (regexState->numCaptures + 1));
return execResult;
}
@@ -6071,7 +6016,7 @@ boost::intrusive_ptr<Expression> ExpressionRegexFind::parse(
BSONElement expr,
const VariablesParseState& vpsIn) {
auto opName = "$regexFind"_sd;
- auto[input, regex, options] = CommonRegexParse(expCtx, expr, vpsIn, opName);
+ auto [input, regex, options] = CommonRegexParse(expCtx, expr, vpsIn, opName);
return new ExpressionRegexFind(
expCtx, std::move(input), std::move(regex), std::move(options), opName);
}
@@ -6092,7 +6037,7 @@ boost::intrusive_ptr<Expression> ExpressionRegexFindAll::parse(
BSONElement expr,
const VariablesParseState& vpsIn) {
auto opName = "$regexFindAll"_sd;
- auto[input, regex, options] = CommonRegexParse(expCtx, expr, vpsIn, opName);
+ auto [input, regex, options] = CommonRegexParse(expCtx, expr, vpsIn, opName);
return new ExpressionRegexFindAll(
expCtx, std::move(input), std::move(regex), std::move(options), opName);
}
@@ -6153,7 +6098,7 @@ boost::intrusive_ptr<Expression> ExpressionRegexMatch::parse(
BSONElement expr,
const VariablesParseState& vpsIn) {
auto opName = "$regexMatch"_sd;
- auto[input, regex, options] = CommonRegexParse(expCtx, expr, vpsIn, opName);
+ auto [input, regex, options] = CommonRegexParse(expCtx, expr, vpsIn, opName);
return new ExpressionRegexMatch(
expCtx, std::move(input), std::move(regex), std::move(options), opName);
}