in sql_utils/public/functions/date_time_util.cc [2989:3065]
absl::Status AddDateOverflow(int32_t date, DateTimestampPart part,
int32_t interval, int32_t* output,
bool* had_overflow) {
*had_overflow = false;
if (!IsValidDate(date)) {
return MakeEvalError() << "Invalid date value: " << date;
}
// Special cases to avoid computing converted_date.
if (part == DAY) {
if (!Add<int32_t>(date, interval, output, kNoError)) {
*had_overflow = true;
return absl::OkStatus();
}
} else if (part == WEEK) {
if (!Multiply<int32_t>(7, interval, &interval, kNoError) ||
!Add<int32_t>(date, interval, output, kNoError)) {
*had_overflow = true;
return absl::OkStatus();
}
} else if (part == YEAR || part == QUARTER || part == MONTH) {
absl::CivilDay civil_day = EpochDaysToCivilDay(date);
// cast is safe, checked with IsValidDate.
int y = static_cast<int32_t>(civil_day.year());
int month = civil_day.month();
int day = civil_day.day();
switch (part) {
case YEAR: {
if (!Add<int32_t>(y, interval, &y, kNoError)) {
*had_overflow = true;
return absl::OkStatus();
}
AdjustYearMonthDay(&y, &month, &day);
absl::CivilDay date_value;
if (!MakeDate(y, month, day, &date_value)) {
*had_overflow = true;
return absl::OkStatus();
}
*output = CivilDayToEpochDays(date_value);
break;
}
case QUARTER:
if (!Multiply<int32_t>(3, interval, &interval, kNoError)) {
*had_overflow = true;
return absl::OkStatus();
}
ABSL_FALLTHROUGH_INTENDED;
case MONTH: {
int32_t m;
if (!Add<int32_t>(month, interval, &m, kNoError)) {
*had_overflow = true;
return absl::OkStatus();
}
AdjustYearMonthDay(&y, &m, &day);
absl::CivilDay date_value;
if (!MakeDate(y, m, day, &date_value)) {
*had_overflow = true;
return absl::OkStatus();
}
*output = CivilDayToEpochDays(date_value);
break;
}
default:
// Do nothing.
break;
}
} else { // Other DateTimestampPart are not supported.
return MakeEvalError() << "Unsupported DateTimestampPart "
<< DateTimestampPart_Name(part);
}
if (!IsValidDate(*output)) {
*had_overflow = true;
return absl::OkStatus();
}
return absl::OkStatus();
}