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:
@ -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.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user