1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-15 03:41:20 +03:00

Refactor jsonpath's compareDatetime()

This commit refactors come ridiculous coding in compareDatetime().  Also, it
provides correct cross-datatype comparison even when one of values overflows
during cast.  That eliminates dilemma on whether we should suppress overflow
errors during cast.

Reported-by: Tom Lane
Discussion: https://postgr.es/m/32308.1569455803%40sss.pgh.pa.us
Discussion: https://postgr.es/m/a5629d0c-8162-7559-16aa-0c8390d6ba5f%40postgrespro.ru
Author: Nikita Glukhov, Alexander Korotkov
This commit is contained in:
Alexander Korotkov
2019-10-21 23:04:14 +03:00
parent a6888fde7f
commit 52ad1e6599
7 changed files with 237 additions and 144 deletions

View File

@@ -5190,12 +5190,12 @@ timestamp_timestamptz(PG_FUNCTION_ARGS)
/*
* Convert timestamp to timestamp with time zone.
*
* If 'have_error' is NULL, then errors are thrown, else '*have_error' is set
* and zero is returned.
* On overflow error is thrown if 'overflow' is NULL. Otherwise, '*overflow'
* is set to -1 (+1) when result value exceed lower (upper) boundary and zero
* returned.
*/
TimestampTz
timestamp2timestamptz_opt_error(Timestamp timestamp, bool *have_error)
timestamp2timestamptz_opt_overflow(Timestamp timestamp, int *overflow)
{
TimestampTz result;
struct pg_tm tt,
@@ -5216,30 +5216,33 @@ timestamp2timestamptz_opt_error(Timestamp timestamp, bool *have_error)
{
return result;
}
else if (have_error)
else if (overflow)
{
*have_error = true;
if (result < MIN_TIMESTAMP)
*overflow = -1;
else
{
Assert(result >= END_TIMESTAMP);
*overflow = 1;
}
return (TimestampTz) 0;
}
}
if (have_error)
*have_error = true;
else
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
ereport(ERROR,
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
return 0;
}
/*
* Single-argument version of timestamp2timestamptz_opt_error().
* Single-argument version of timestamp2timestamptz_opt_overflow().
*/
static TimestampTz
timestamp2timestamptz(Timestamp timestamp)
{
return timestamp2timestamptz_opt_error(timestamp, NULL);
return timestamp2timestamptz_opt_overflow(timestamp, NULL);
}
/* timestamptz_timestamp()