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";
}
}