postgres.git / summary / log / commit / refs

commit    d7f10705b46a9c618b452e246d3d394e5a1a707f
Author:   Bruce Momjian <bruce@momjian.us>
Date:     Thu Mar 20 06:03:00 2003 +0000
First released in: 7.4

    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


src/backend/utils/adt/timestamp.c | 5 ++- .../expected/horology-no-DST-before-1970.out | 44 +++++++++++----------- .../regress/expected/horology-solaris-1947.out | 44 +++++++++++----------- src/test/regress/expected/horology.out | 44 +++++++++++----------- src/test/regress/sql/horology.sql | 8 ++-- 5 files changed, 74 insertions(+), 71 deletions(-) diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index 2764fee906a..feaec85b69e 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.80 2003/03/11 21:01:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.81 2003/03/20 06:02:59 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -964,6 +964,9 @@ tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, Timestamp *result) time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec); #ifdef HAVE_INT64_TIMESTAMP *result = ((date * INT64CONST(86400000000)) + time); + if ((*result < 0 && date >= 0) || (*result >= 0 && date < 0)) + elog(ERROR, "TIMESTAMP out of range '%04d-%02d-%02d'", + tm->tm_year, tm->tm_mon, tm->tm_mday); #else *result = ((date * 86400) + time); #endif diff --git a/src/test/regress/expected/horology-no-DST-before-1970.out b/src/test/regress/expected/horology-no-DST-before-1970.out index 5a191c9370c..269c169c623 100644 --- a/src/test/regress/expected/horology-no-DST-before-1970.out +++ b/src/test/regress/expected/horology-no-DST-before-1970.out @@ -328,28 +328,28 @@ SELECT timestamp without time zone '1999-12-01' + interval '1 month - 1 second' Fri Dec 31 23:59:59 1999 (1 row) -SELECT timestamp without time zone 'Nov 24, 4714 BC' + interval '1000000000 days' AS "Nov 27, 2733194"; - Nov 27, 2733194 ------------------------------ - Sun Nov 27 00:00:00 2733194 -(1 row) - -SELECT timestamp without time zone 'Nov 24, 4714 BC' + interval '2000000000 days' AS "Nov 30, 5471101"; - Nov 30, 5471101 ------------------------------ - Sat Nov 30 00:00:00 5471101 -(1 row) - -SELECT timestamp without time zone 'Nov 25, 4714 BC' + interval '2147483492 days' AS "Dec 31, 5874897"; - Dec 31, 5874897 ------------------------------ - Tue Dec 31 00:00:00 5874897 -(1 row) - -SELECT timestamp without time zone '12/31/5874897' - timestamp without time zone 'Nov 24, 4714 BC' AS "2147483493 Days"; - 2147483493 Days -------------------- - @ 2147483493 days +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '106000000 days' AS "Feb 23, 285506"; + Feb 23, 285506 +---------------------------- + Fri Feb 23 00:00:00 285506 + (1 row) + +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '107000000 days' AS "Jan 20, 288244"; + Jan 20, 288244 +---------------------------- + Sat Jan 20 00:00:00 288244 + (1 row) + +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '109203489 days' AS "Dec 31, 294276"; + Dec 31, 294276 +---------------------------- + Sun Dec 31 00:00:00 294276 + (1 row) + +SELECT timestamp without time zone '12/31/294276' - timestamp without time zone '12/23/1999' AS "106751991 Days"; + 106751991 Days +------------------ + @ 106751991 days (1 row) -- Shorthand values diff --git a/src/test/regress/expected/horology-solaris-1947.out b/src/test/regress/expected/horology-solaris-1947.out index 784900531d7..73402c1ead4 100644 --- a/src/test/regress/expected/horology-solaris-1947.out +++ b/src/test/regress/expected/horology-solaris-1947.out @@ -328,28 +328,28 @@ SELECT timestamp without time zone '1999-12-01' + interval '1 month - 1 second' Fri Dec 31 23:59:59 1999 (1 row) -SELECT timestamp without time zone 'Nov 24, 4714 BC' + interval '1000000000 days' AS "Nov 27, 2733194"; - Nov 27, 2733194 ------------------------------ - Sun Nov 27 00:00:00 2733194 -(1 row) - -SELECT timestamp without time zone 'Nov 24, 4714 BC' + interval '2000000000 days' AS "Nov 30, 5471101"; - Nov 30, 5471101 ------------------------------ - Sat Nov 30 00:00:00 5471101 -(1 row) - -SELECT timestamp without time zone 'Nov 25, 4714 BC' + interval '2147483492 days' AS "Dec 31, 5874897"; - Dec 31, 5874897 ------------------------------ - Tue Dec 31 00:00:00 5874897 -(1 row) - -SELECT timestamp without time zone '12/31/5874897' - timestamp without time zone 'Nov 24, 4714 BC' AS "2147483493 Days"; - 2147483493 Days -------------------- - @ 2147483493 days +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '106000000 days' AS "Feb 23, 285506"; + Feb 23, 285506 +---------------------------- + Fri Feb 23 00:00:00 285506 + (1 row) + +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '107000000 days' AS "Jan 20, 288244"; + Jan 20, 288244 +---------------------------- + Sat Jan 20 00:00:00 288244 + (1 row) + +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '109203489 days' AS "Dec 31, 294276"; + Dec 31, 294276 +---------------------------- + Sun Dec 31 00:00:00 294276 + (1 row) + +SELECT timestamp without time zone '12/31/294276' - timestamp without time zone '12/23/1999' AS "106751991 Days"; + 106751991 Days +------------------ + @ 106751991 days (1 row) -- Shorthand values diff --git a/src/test/regress/expected/horology.out b/src/test/regress/expected/horology.out index d91df1bd829..831806c992b 100644 --- a/src/test/regress/expected/horology.out +++ b/src/test/regress/expected/horology.out @@ -328,28 +328,28 @@ SELECT timestamp without time zone '1999-12-01' + interval '1 month - 1 second' Fri Dec 31 23:59:59 1999 (1 row) -SELECT timestamp without time zone 'Nov 24, 4714 BC' + interval '1000000000 days' AS "Nov 27, 2733194"; - Nov 27, 2733194 ------------------------------ - Sun Nov 27 00:00:00 2733194 -(1 row) - -SELECT timestamp without time zone 'Nov 24, 4714 BC' + interval '2000000000 days' AS "Nov 30, 5471101"; - Nov 30, 5471101 ------------------------------ - Sat Nov 30 00:00:00 5471101 -(1 row) - -SELECT timestamp without time zone 'Nov 25, 4714 BC' + interval '2147483492 days' AS "Dec 31, 5874897"; - Dec 31, 5874897 ------------------------------ - Tue Dec 31 00:00:00 5874897 -(1 row) - -SELECT timestamp without time zone '12/31/5874897' - timestamp without time zone 'Nov 24, 4714 BC' AS "2147483493 Days"; - 2147483493 Days -------------------- - @ 2147483493 days +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '106000000 days' AS "Feb 23, 285506"; + Feb 23, 285506 +---------------------------- + Fri Feb 23 00:00:00 285506 + (1 row) + +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '107000000 days' AS "Jan 20, 288244"; + Jan 20, 288244 +---------------------------- + Sat Jan 20 00:00:00 288244 + (1 row) + +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '109203489 days' AS "Dec 31, 294276"; + Dec 31, 294276 +---------------------------- + Sun Dec 31 00:00:00 294276 + (1 row) + +SELECT timestamp without time zone '12/31/294276' - timestamp without time zone '12/23/1999' AS "106751991 Days"; + 106751991 Days +------------------ + @ 106751991 days (1 row) -- Shorthand values diff --git a/src/test/regress/sql/horology.sql b/src/test/regress/sql/horology.sql index 0ff15e9711f..88ac83b5add 100644 --- a/src/test/regress/sql/horology.sql +++ b/src/test/regress/sql/horology.sql @@ -76,10 +76,10 @@ SELECT timestamp without time zone '1996-03-01' - interval '1 second' AS "Feb 29 SELECT timestamp without time zone '1999-03-01' - interval '1 second' AS "Feb 28"; SELECT timestamp without time zone '2000-03-01' - interval '1 second' AS "Feb 29"; SELECT timestamp without time zone '1999-12-01' + interval '1 month - 1 second' AS "Dec 31"; -SELECT timestamp without time zone 'Nov 24, 4714 BC' + interval '1000000000 days' AS "Nov 27, 2733194"; -SELECT timestamp without time zone 'Nov 24, 4714 BC' + interval '2000000000 days' AS "Nov 30, 5471101"; -SELECT timestamp without time zone 'Nov 25, 4714 BC' + interval '2147483492 days' AS "Dec 31, 5874897"; -SELECT timestamp without time zone '12/31/5874897' - timestamp without time zone 'Nov 24, 4714 BC' AS "2147483493 Days"; +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '106000000 days' AS "Feb 23, 285506"; +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '107000000 days' AS "Jan 20, 288244"; +SELECT timestamp without time zone 'Jan 1, 4713 BC' + interval '109203489 days' AS "Dec 31, 294276"; +SELECT timestamp without time zone '12/31/294276' - timestamp without time zone '12/23/1999' AS "106751991 Days"; -- Shorthand values -- Not directly usable for regression testing since these are not constants. [parent: be1c6e75293f]