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.cpp59
1 files changed, 47 insertions, 12 deletions
diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp
index c1bf5957066..b965b86f244 100644
--- a/src/mongo/db/pipeline/expression.cpp
+++ b/src/mongo/db/pipeline/expression.cpp
@@ -1204,7 +1204,7 @@ Value ExpressionDateFromParts::serialize(bool explain) const {
}
bool ExpressionDateFromParts::evaluateNumberWithDefault(const Document& root,
- intrusive_ptr<Expression> field,
+ const Expression* field,
StringData fieldName,
long long defaultValue,
long long* returnValue,
@@ -1232,14 +1232,39 @@ bool ExpressionDateFromParts::evaluateNumberWithDefault(const Document& root,
return true;
}
+bool ExpressionDateFromParts::evaluateNumberWithDefaultAndBounds(const Document& root,
+ const Expression* field,
+ StringData fieldName,
+ long long defaultValue,
+ long long* returnValue,
+ Variables* variables) const {
+ 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));
+
+ return result;
+}
+
Value ExpressionDateFromParts::evaluate(const Document& root, Variables* variables) const {
long long hour, minute, second, millisecond;
- if (!evaluateNumberWithDefault(root, _hour, "hour"_sd, 0, &hour, variables) ||
- !evaluateNumberWithDefault(root, _minute, "minute"_sd, 0, &minute, variables) ||
- !evaluateNumberWithDefault(root, _second, "second"_sd, 0, &second, variables) ||
+ if (!evaluateNumberWithDefaultAndBounds(root, _hour.get(), "hour"_sd, 0, &hour, variables) ||
+ !evaluateNumberWithDefaultAndBounds(
+ root, _minute.get(), "minute"_sd, 0, &minute, variables) ||
+ !evaluateNumberWithDefault(root, _second.get(), "second"_sd, 0, &second, variables) ||
!evaluateNumberWithDefault(
- root, _millisecond, "millisecond"_sd, 0, &millisecond, variables)) {
+ root, _millisecond.get(), "millisecond"_sd, 0, &millisecond, variables)) {
// One of the evaluated inputs in nullish.
return Value(BSONNULL);
}
@@ -1254,9 +1279,10 @@ Value ExpressionDateFromParts::evaluate(const Document& root, Variables* variabl
if (_year) {
long long year, month, day;
- if (!evaluateNumberWithDefault(root, _year, "year"_sd, 1970, &year, variables) ||
- !evaluateNumberWithDefault(root, _month, "month"_sd, 1, &month, variables) ||
- !evaluateNumberWithDefault(root, _day, "day"_sd, 1, &day, variables)) {
+ if (!evaluateNumberWithDefault(root, _year.get(), "year"_sd, 1970, &year, variables) ||
+ !evaluateNumberWithDefaultAndBounds(
+ root, _month.get(), "month"_sd, 1, &month, variables) ||
+ !evaluateNumberWithDefaultAndBounds(root, _day.get(), "day"_sd, 1, &day, variables)) {
// One of the evaluated inputs in nullish.
return Value(BSONNULL);
}
@@ -1276,14 +1302,23 @@ Value ExpressionDateFromParts::evaluate(const Document& root, Variables* variabl
long long isoWeekYear, isoWeek, isoDayOfWeek;
if (!evaluateNumberWithDefault(
- root, _isoWeekYear, "isoWeekYear"_sd, 1970, &isoWeekYear, variables) ||
- !evaluateNumberWithDefault(root, _isoWeek, "isoWeek"_sd, 1, &isoWeek, variables) ||
- !evaluateNumberWithDefault(
- root, _isoDayOfWeek, "isoDayOfWeek"_sd, 1, &isoDayOfWeek, variables)) {
+ root, _isoWeekYear.get(), "isoWeekYear"_sd, 1970, &isoWeekYear, variables) ||
+ !evaluateNumberWithDefaultAndBounds(
+ root, _isoWeek.get(), "isoWeek"_sd, 1, &isoWeek, variables) ||
+ !evaluateNumberWithDefaultAndBounds(
+ root, _isoDayOfWeek.get(), "isoDayOfWeek"_sd, 1, &isoDayOfWeek, variables)) {
// One of the evaluated inputs in nullish.
return Value(BSONNULL);
}
+ uassert(31095,
+ str::stream() << "'isoWeekYear' must evaluate to an integer in the range " << 0
+ << " to "
+ << 9999
+ << ", found "
+ << isoWeekYear,
+ isoWeekYear >= 0 && isoWeekYear <= 9999);
+
return Value(timeZone->createFromIso8601DateParts(
isoWeekYear, isoWeek, isoDayOfWeek, hour, minute, second, millisecond));
}