diff options
author | Alexander Korotkov <akorotkov@postgresql.org> | 2019-10-21 23:04:14 +0300 |
---|---|---|
committer | Alexander Korotkov <akorotkov@postgresql.org> | 2019-10-21 23:07:07 +0300 |
commit | 52ad1e659967896ed153185328ffe806d69abcb6 (patch) | |
tree | 03ab5a5db0c8bac802160dcf538a38a4025f92c9 /src/backend/utils/adt/timestamp.c | |
parent | a6888fde7f0dbe865559b31ba2ce01ac1150debe (diff) | |
download | postgresql-52ad1e659967896ed153185328ffe806d69abcb6.tar.gz postgresql-52ad1e659967896ed153185328ffe806d69abcb6.zip |
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
Diffstat (limited to 'src/backend/utils/adt/timestamp.c')
-rw-r--r-- | src/backend/utils/adt/timestamp.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index 90ebb50e1f5..1dc4c820de2 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -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() |