1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-16 06:01:02 +03:00

Allow to_timestamp(float8) to convert float infinity to timestamp infinity.

With the original SQL-function implementation, such cases failed because
we don't support infinite intervals.  Converting the function to C lets
us bypass the interval representation, which should be a bit faster as
well as more flexible.

Vitaly Burovoy, reviewed by Anastasia Lubennikova
This commit is contained in:
Tom Lane
2016-03-29 17:09:21 -04:00
parent 96f8373cad
commit e511d878f3
7 changed files with 149 additions and 26 deletions

View File

@ -737,6 +737,64 @@ make_timestamptz_at_timezone(PG_FUNCTION_ARGS)
PG_RETURN_TIMESTAMPTZ(result);
}
/*
* to_timestamp(double precision)
* Convert UNIX epoch to timestamptz.
*/
Datum
float8_timestamptz(PG_FUNCTION_ARGS)
{
float8 seconds = PG_GETARG_FLOAT8(0);
TimestampTz result;
/* Deal with NaN and infinite inputs ... */
if (isnan(seconds))
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp cannot be NaN")));
if (isinf(seconds))
{
if (seconds < 0)
TIMESTAMP_NOBEGIN(result);
else
TIMESTAMP_NOEND(result);
}
else
{
/* Out of range? */
if (seconds <
(float8) SECS_PER_DAY * (DATETIME_MIN_JULIAN - UNIX_EPOCH_JDATE))
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range: \"%g\"", seconds)));
if (seconds >=
(float8) SECS_PER_DAY * (TIMESTAMP_END_JULIAN - UNIX_EPOCH_JDATE))
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range: \"%g\"", seconds)));
/* Convert UNIX epoch to Postgres epoch */
seconds -= ((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);
#ifdef HAVE_INT64_TIMESTAMP
result = seconds * USECS_PER_SEC;
#else
result = seconds;
#endif
/* Recheck in case roundoff produces something just out of range */
if (!IS_VALID_TIMESTAMP(result))
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range: \"%g\"",
PG_GETARG_FLOAT8(0))));
}
PG_RETURN_TIMESTAMP(result);
}
/* timestamptz_out()
* Convert a timestamp to external form.
*/