static bool AddAtLeastDaysToCivilTime()

in sql_utils/public/functions/date_time_util.cc [774:853]


static bool AddAtLeastDaysToCivilTime(DateTimestampPart part, int32_t interval,
                                      absl::CivilSecond cs, int subsecond,
                                      absl::TimeZone timezone,
                                      TimestampScale scale,
                                      absl::Time* result_timestamp) {
  switch (part) {
    case YEAR: {
      int year;
      // cast is safe, given method contract.
      if (!Add<int32_t>(static_cast<int32_t>(cs.year()), interval, &year,
                        kNoError)) {
        return false;
      }
      int month = cs.month();
      int day = cs.day();
      AdjustYearMonthDay(&year, &month, &day);
      if (!TimestampFromParts(year, month, day, cs.hour(), cs.minute(),
                              cs.second(), subsecond, scale, timezone,
                              result_timestamp)) {
        return false;
      }
      break;
    }
    case QUARTER:
      if (!Multiply<int32_t>(interval, 3, &interval, kNoError)) {
        return false;
      }
      ABSL_FALLTHROUGH_INTENDED;
    case MONTH: {
      int32_t month;
      if (!Add<int32_t>(cs.month(), interval, &month, kNoError)) {
        return false;
      }
      int day = cs.day();
      // cast is safe, given method contract.
      int year = static_cast<int32_t>(cs.year());
      AdjustYearMonthDay(&year, &month, &day);
      if (!TimestampFromParts(year, month, day, cs.hour(), cs.minute(),
                              cs.second(), subsecond, scale, timezone,
                              result_timestamp)) {
        return false;
      }
      break;
    }
    case WEEK:
      if (!Multiply<int32_t>(interval, 7, &interval, kNoError)) {
        return false;
      }
      ABSL_FALLTHROUGH_INTENDED;
    case DAY: {
      absl::CivilDay date;
      // cast is safe, given method contract.
      if (!MakeDate(static_cast<int32_t>(cs.year()), cs.month(), cs.day(),
                    &date)) {
        // This is unreachable since the input timestamp is valid and
        // therefore cannot be outside the Date range bounds.
        return false;
      }
      // This could probably be simplified to avoid bouncing back and forth
      // between civil day, but its not clear how important it is to preserve
      // exact overflow semantics, or how that would interact with
      // absl::CivilDay (which encodes days simply as 'int').
      int days = CivilDayToEpochDays(date);
      if (!Add<int32_t>(days, interval, &days, kNoError)) {
        return false;
      }
      date = EpochDaysToCivilDay(days);
      if (!TimestampFromParts(date.year(), date.month(), date.day(), cs.hour(),
                              cs.minute(), cs.second(), subsecond, scale,
                              timezone, result_timestamp)) {
        return false;
      }
      break;
    }
    default:
      SQL_DCHECK(false) << "Should not reach here";
      return false;
  }
  return true;
}