summaryrefslogtreecommitdiff
path: root/src/include/utils
diff options
context:
space:
mode:
authorTom Lane2020-10-07 21:10:26 +0000
committerTom Lane2020-10-07 21:10:26 +0000
commit3db322eaab9688d57643b4d2a5f52b7f350ef46f (patch)
tree66318bc8ee6d673df3b6dbc67de45bf8d0ec590f /src/include/utils
parent6c05e5b77471dfadebe50ad4a8bdedef02ad0078 (diff)
Prevent internal overflows in date-vs-timestamp and related comparisons.
The date-vs-timestamp, date-vs-timestamptz, and timestamp-vs-timestamptz comparators all worked by promoting the first type to the second and then doing a simple same-type comparison. This works fine, except when the conversion result is out of range, in which case we throw an entirely avoidable error. The sources of such failures are (a) type date can represent dates much farther in the future than the timestamp types can; (b) timezone rotation might cause a just-in-range timestamp value to become a just-out-of-range timestamptz value. Up to now we just ignored these corner-case issues, but now we have an actual user complaint (bug #16657 from Huss EL-Sheikh), so let's do something about it. It turns out that commit 52ad1e659 already built all the necessary infrastructure to support error-free comparisons, but neglected to actually use it in the main-line code paths. Fix that, do a little bit of code style review, and remove the now-duplicate logic in jsonpath_exec.c. Back-patch to v13 where 52ad1e659 came in. We could take this back further by back-patching said infrastructure, but given the small number of complaints so far, I don't feel a great need to. Discussion: https://postgr.es/m/16657-cde2f876d8cc7971@postgresql.org
Diffstat (limited to 'src/include/utils')
-rw-r--r--src/include/utils/date.h3
-rw-r--r--src/include/utils/timestamp.h2
2 files changed, 5 insertions, 0 deletions
diff --git a/src/include/utils/date.h b/src/include/utils/date.h
index 4cdb1f97cc8..6fc491e6a6d 100644
--- a/src/include/utils/date.h
+++ b/src/include/utils/date.h
@@ -72,6 +72,9 @@ extern int32 anytime_typmod_check(bool istz, int32 typmod);
extern double date2timestamp_no_overflow(DateADT dateVal);
extern Timestamp date2timestamp_opt_overflow(DateADT dateVal, int *overflow);
extern TimestampTz date2timestamptz_opt_overflow(DateADT dateVal, int *overflow);
+extern int32 date_cmp_timestamp_internal(DateADT dateVal, Timestamp dt2);
+extern int32 date_cmp_timestamptz_internal(DateADT dateVal, TimestampTz dt2);
+
extern void EncodeSpecialDate(DateADT dt, char *str);
extern DateADT GetSQLCurrentDate(void);
extern TimeTzADT *GetSQLCurrentTime(int32 typmod);
diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h
index 03a1de569f0..16c3fd8ec97 100644
--- a/src/include/utils/timestamp.h
+++ b/src/include/utils/timestamp.h
@@ -99,6 +99,8 @@ extern int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2);
extern TimestampTz timestamp2timestamptz_opt_overflow(Timestamp timestamp,
int *overflow);
+extern int32 timestamp_cmp_timestamptz_internal(Timestamp timestampVal,
+ TimestampTz dt2);
extern int isoweek2j(int year, int week);
extern void isoweek2date(int woy, int *year, int *mon, int *mday);