absl::Status TruncateDatetime()

in sql_utils/public/functions/date_time_util.cc [3931:3989]


absl::Status TruncateDatetime(const DatetimeValue& datetime,
                              DateTimestampPart part, DatetimeValue* output) {
  if (!datetime.IsValid()) {
    return MakeEvalError() << "Invalid datetime value: "
                           << datetime.DebugString();
  }
  switch (part) {
    case YEAR:
    case ISOYEAR:
    case QUARTER:
    case MONTH:
    case WEEK:
    case ISOWEEK:
    case WEEK_MONDAY:
    case WEEK_TUESDAY:
    case WEEK_WEDNESDAY:
    case WEEK_THURSDAY:
    case WEEK_FRIDAY:
    case WEEK_SATURDAY:
    case DAY: {
      int32_t date;
      SQL_RETURN_IF_ERROR(ExtractFromDatetime(DATE, datetime, &date));
      SQL_RETURN_IF_ERROR(TruncateDate(date, part, &date));
      if (!IsValidDate(date)) {
        return MakeEvalError() << "Truncating " << datetime.DebugString()
                               << " to " << DateTimestampPart_Name(part)
                               << " produces an invalid Datetime value";
      }
      return ConstructDatetime(date, TimeValue() /* 00:00:00 */, output);
    }
    case HOUR:
    case MINUTE:
    case SECOND:
    case MILLISECOND:
    case MICROSECOND:
    case NANOSECOND: {
      int32_t date;
      SQL_RETURN_IF_ERROR(ExtractFromDatetime(DATE, datetime, &date));

      TimeValue time;
      SQL_RETURN_IF_ERROR(ExtractTimeFromDatetime(datetime, &time));
      SQL_RETURN_IF_ERROR(TruncateTime(time, part, &time));

      return ConstructDatetime(date, time, output);
    }
    case DAYOFWEEK:
    case DAYOFYEAR:
    case DATE:
    case DATETIME:
    case TIME:
      return MakeEvalError()
             << "Unsupported DateTimestampPart " << DateTimestampPart_Name(part)
             << " for TIME_TRUNC";
    default:
      return MakeEvalError()
             << "Unexpected DateTimestampPart " << DateTimestampPart_Name(part)
             << " for TIME_TRUNC";
  }
}