Skip to content

Commit d7f1070

Browse files
committed
Attached is a patch that limits the range tested by horology to
what is capable using integer-datatime timestamps. It does attempt to exercise the maximum allowable timestamp range. Also is a small error check when converting a timestamp from external to internal format that prevents out of range timestamps from being entered. Files patched: Index: src/backend/utils/adt/timestamp.c Added range check to prevent out of range timestamps from being used. Index: src/test/regress/sql/horology.sql Index: src/test/regress/expected/horology-no-DST-before-1970.out Index: src/test/regress/expected/horology-solaris-1947.out Limited range of timestamps being checked to Jan 1, 4713 BC to Dec 31, 294276 In creating this patch, I have seen some definite problems with integer timestamps and how they react when used near their limits. For example, the following statement gives the correct result: SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '109203489 days' AS "Dec 31, 294276"; However, this statement which is the logical inverse of the above gives incorrect results: SELECT timestamp without time zone '12/31/294276' - timestamp without time zone 'Jan 1, 4713 BC' AS "109203489 Days"; John Cochran
1 parent be1c6e7 commit d7f1070

File tree

5 files changed

+74
-71
lines changed

5 files changed

+74
-71
lines changed

src/backend/utils/adt/timestamp.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.80 2003/03/11 21:01:33 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.81 2003/03/20 06:02:59 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -964,6 +964,9 @@ tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, Timestamp *result)
964964
time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
965965
#ifdef HAVE_INT64_TIMESTAMP
966966
*result = ((date * INT64CONST(86400000000)) + time);
967+
if ((*result < 0 && date >= 0) || (*result >= 0 && date < 0))
968+
elog(ERROR, "TIMESTAMP out of range '%04d-%02d-%02d'",
969+
tm->tm_year, tm->tm_mon, tm->tm_mday);
967970
#else
968971
*result = ((date * 86400) + time);
969972
#endif

src/test/regress/expected/horology-no-DST-before-1970.out

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -328,28 +328,28 @@ SELECT timestamp without time zone '1999-12-01' + interval '1 month - 1 second'
328328
Fri Dec 31 23:59:59 1999
329329
(1 row)
330330

331-
SELECT timestamp without time zone 'Nov 24, 4714 BC' + interval '1000000000 days' AS "Nov 27, 2733194";
332-
Nov 27, 2733194
333-
-----------------------------
334-
Sun Nov 27 00:00:00 2733194
335-
(1 row)
336-
337-
SELECT timestamp without time zone 'Nov 24, 4714 BC' + interval '2000000000 days' AS "Nov 30, 5471101";
338-
Nov 30, 5471101
339-
-----------------------------
340-
Sat Nov 30 00:00:00 5471101
341-
(1 row)
342-
343-
SELECT timestamp without time zone 'Nov 25, 4714 BC' + interval '2147483492 days' AS "Dec 31, 5874897";
344-
Dec 31, 5874897
345-
-----------------------------
346-
Tue Dec 31 00:00:00 5874897
347-
(1 row)
348-
349-
SELECT timestamp without time zone '12/31/5874897' - timestamp without time zone 'Nov 24, 4714 BC' AS "2147483493 Days";
350-
2147483493 Days
351-
-------------------
352-
@ 2147483493 days
331+
SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '106000000 days' AS "Feb 23, 285506";
332+
Feb 23, 285506
333+
----------------------------
334+
Fri Feb 23 00:00:00 285506
335+
(1 row)
336+
337+
SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '107000000 days' AS "Jan 20, 288244";
338+
Jan 20, 288244
339+
----------------------------
340+
Sat Jan 20 00:00:00 288244
341+
(1 row)
342+
343+
SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '109203489 days' AS "Dec 31, 294276";
344+
Dec 31, 294276
345+
----------------------------
346+
Sun Dec 31 00:00:00 294276
347+
(1 row)
348+
349+
SELECT timestamp without time zone '12/31/294276' - timestamp without time zone '12/23/1999' AS "106751991 Days";
350+
106751991 Days
351+
------------------
352+
@ 106751991 days
353353
(1 row)
354354

355355
-- Shorthand values

src/test/regress/expected/horology-solaris-1947.out

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -328,28 +328,28 @@ SELECT timestamp without time zone '1999-12-01' + interval '1 month - 1 second'
328328
Fri Dec 31 23:59:59 1999
329329
(1 row)
330330

331-
SELECT timestamp without time zone 'Nov 24, 4714 BC' + interval '1000000000 days' AS "Nov 27, 2733194";
332-
Nov 27, 2733194
333-
-----------------------------
334-
Sun Nov 27 00:00:00 2733194
335-
(1 row)
336-
337-
SELECT timestamp without time zone 'Nov 24, 4714 BC' + interval '2000000000 days' AS "Nov 30, 5471101";
338-
Nov 30, 5471101
339-
-----------------------------
340-
Sat Nov 30 00:00:00 5471101
341-
(1 row)
342-
343-
SELECT timestamp without time zone 'Nov 25, 4714 BC' + interval '2147483492 days' AS "Dec 31, 5874897";
344-
Dec 31, 5874897
345-
-----------------------------
346-
Tue Dec 31 00:00:00 5874897
347-
(1 row)
348-
349-
SELECT timestamp without time zone '12/31/5874897' - timestamp without time zone 'Nov 24, 4714 BC' AS "2147483493 Days";
350-
2147483493 Days
351-
-------------------
352-
@ 2147483493 days
331+
SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '106000000 days' AS "Feb 23, 285506";
332+
Feb 23, 285506
333+
----------------------------
334+
Fri Feb 23 00:00:00 285506
335+
(1 row)
336+
337+
SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '107000000 days' AS "Jan 20, 288244";
338+
Jan 20, 288244
339+
----------------------------
340+
Sat Jan 20 00:00:00 288244
341+
(1 row)
342+
343+
SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '109203489 days' AS "Dec 31, 294276";
344+
Dec 31, 294276
345+
----------------------------
346+
Sun Dec 31 00:00:00 294276
347+
(1 row)
348+
349+
SELECT timestamp without time zone '12/31/294276' - timestamp without time zone '12/23/1999' AS "106751991 Days";
350+
106751991 Days
351+
------------------
352+
@ 106751991 days
353353
(1 row)
354354

355355
-- Shorthand values

src/test/regress/expected/horology.out

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -328,28 +328,28 @@ SELECT timestamp without time zone '1999-12-01' + interval '1 month - 1 second'
328328
Fri Dec 31 23:59:59 1999
329329
(1 row)
330330

331-
SELECT timestamp without time zone 'Nov 24, 4714 BC' + interval '1000000000 days' AS "Nov 27, 2733194";
332-
Nov 27, 2733194
333-
-----------------------------
334-
Sun Nov 27 00:00:00 2733194
335-
(1 row)
336-
337-
SELECT timestamp without time zone 'Nov 24, 4714 BC' + interval '2000000000 days' AS "Nov 30, 5471101";
338-
Nov 30, 5471101
339-
-----------------------------
340-
Sat Nov 30 00:00:00 5471101
341-
(1 row)
342-
343-
SELECT timestamp without time zone 'Nov 25, 4714 BC' + interval '2147483492 days' AS "Dec 31, 5874897";
344-
Dec 31, 5874897
345-
-----------------------------
346-
Tue Dec 31 00:00:00 5874897
347-
(1 row)
348-
349-
SELECT timestamp without time zone '12/31/5874897' - timestamp without time zone 'Nov 24, 4714 BC' AS "2147483493 Days";
350-
2147483493 Days
351-
-------------------
352-
@ 2147483493 days
331+
SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '106000000 days' AS "Feb 23, 285506";
332+
Feb 23, 285506
333+
----------------------------
334+
Fri Feb 23 00:00:00 285506
335+
(1 row)
336+
337+
SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '107000000 days' AS "Jan 20, 288244";
338+
Jan 20, 288244
339+
----------------------------
340+
Sat Jan 20 00:00:00 288244
341+
(1 row)
342+
343+
SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '109203489 days' AS "Dec 31, 294276";
344+
Dec 31, 294276
345+
----------------------------
346+
Sun Dec 31 00:00:00 294276
347+
(1 row)
348+
349+
SELECT timestamp without time zone '12/31/294276' - timestamp without time zone '12/23/1999' AS "106751991 Days";
350+
106751991 Days
351+
------------------
352+
@ 106751991 days
353353
(1 row)
354354

355355
-- Shorthand values

src/test/regress/sql/horology.sql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,10 @@ SELECT timestamp without time zone '1996-03-01' - interval '1 second' AS "Feb 29
7676
SELECT timestamp without time zone '1999-03-01' - interval '1 second' AS "Feb 28";
7777
SELECT timestamp without time zone '2000-03-01' - interval '1 second' AS "Feb 29";
7878
SELECT timestamp without time zone '1999-12-01' + interval '1 month - 1 second' AS "Dec 31";
79-
SELECT timestamp without time zone 'Nov 24, 4714 BC' + interval '1000000000 days' AS "Nov 27, 2733194";
80-
SELECT timestamp without time zone 'Nov 24, 4714 BC' + interval '2000000000 days' AS "Nov 30, 5471101";
81-
SELECT timestamp without time zone 'Nov 25, 4714 BC' + interval '2147483492 days' AS "Dec 31, 5874897";
82-
SELECT timestamp without time zone '12/31/5874897' - timestamp without time zone 'Nov 24, 4714 BC' AS "2147483493 Days";
79+
SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '106000000 days' AS "Feb 23, 285506";
80+
SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '107000000 days' AS "Jan 20, 288244";
81+
SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '109203489 days' AS "Dec 31, 294276";
82+
SELECT timestamp without time zone '12/31/294276' - timestamp without time zone '12/23/1999' AS "106751991 Days";
8383

8484
-- Shorthand values
8585
-- Not directly usable for regression testing since these are not constants.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy