1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-06 07:49:08 +03:00

Add make_date() and make_time() functions.

Pavel Stehule, reviewed by Jeevan Chalke and Atri Sharma
This commit is contained in:
Tom Lane
2013-11-17 15:06:50 -05:00
parent 69c8fbac20
commit f901bb50e3
9 changed files with 162 additions and 4 deletions

View File

@@ -235,6 +235,43 @@ date_send(PG_FUNCTION_ARGS)
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
/*
* make_date - date constructor
*/
Datum
make_date(PG_FUNCTION_ARGS)
{
struct pg_tm tm;
DateADT date;
int dterr;
tm.tm_year = PG_GETARG_INT32(0);
tm.tm_mon = PG_GETARG_INT32(1);
tm.tm_mday = PG_GETARG_INT32(2);
/*
* Note: we'll reject zero or negative year values. Perhaps negatives
* should be allowed to represent BC years?
*/
dterr = ValidateDate(DTK_DATE_M, false, false, false, &tm);
if (dterr != 0)
ereport(ERROR,
(errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
errmsg("date field value out of range: %d-%02d-%02d",
tm.tm_year, tm.tm_mon, tm.tm_mday)));
if (!IS_VALID_JULIAN(tm.tm_year, tm.tm_mon, tm.tm_mday))
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("date out of range: %d-%02d-%02d",
tm.tm_year, tm.tm_mon, tm.tm_mday)));
date = date2j(tm.tm_year, tm.tm_mon, tm.tm_mday) - POSTGRES_EPOCH_JDATE;
PG_RETURN_DATEADT(date);
}
/*
* Convert reserved date values to string.
*/
@@ -1208,6 +1245,39 @@ timetypmodout(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(anytime_typmodout(false, typmod));
}
/*
* make_time - time constructor
*/
Datum
make_time(PG_FUNCTION_ARGS)
{
int tm_hour = PG_GETARG_INT32(0);
int tm_min = PG_GETARG_INT32(1);
double sec = PG_GETARG_FLOAT8(2);
TimeADT time;
/* This should match the checks in DecodeTimeOnly */
if (tm_hour < 0 || tm_min < 0 || tm_min > MINS_PER_HOUR - 1 ||
sec < 0 || sec > SECS_PER_MINUTE ||
tm_hour > HOURS_PER_DAY ||
/* test for > 24:00:00 */
(tm_hour == HOURS_PER_DAY && (tm_min > 0 || sec > 0)))
ereport(ERROR,
(errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
errmsg("time field value out of range: %d:%02d:%02g",
tm_hour, tm_min, sec)));
/* This should match tm2time */
#ifdef HAVE_INT64_TIMESTAMP
time = (((tm_hour * MINS_PER_HOUR + tm_min) * SECS_PER_MINUTE)
* USECS_PER_SEC) + rint(sec * USECS_PER_SEC);
#else
time = ((tm_hour * MINS_PER_HOUR + tm_min) * SECS_PER_MINUTE) + sec;
#endif
PG_RETURN_TIMEADT(time);
}
/* time_transform()
* Flatten calls to time_scale() and timetz_scale() that solely represent