absl::Status AddDateOverflow()

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();
}