Обсуждение: BUG #4789: ERROR 22008 on timestamp import

Поиск
Список
Период
Сортировка

BUG #4789: ERROR 22008 on timestamp import

От
"Robert Kruuus"
Дата:
The following bug has been logged online:

Bug reference:      4789
Logged by:          Robert Kruuus
Email address:      robert.kruus@gov.sk.ca
PostgreSQL version: 8.3.7
Operating system:   [FREEBSD] amd64-portbld-freebsd7.1, compiled by GCC cc
(GCC) 4.2.1
Description:        ERROR 22008 on timestamp import
Details:

Copying from a csv file (using both COPY as superuser and the psql \copy
command) fails with DATETIME FIELD OVERFLOW for values with x.9999999Z
(seven or more nines after the decimal)
'1999-08-06 05:34:10.999999643Z' and '1999-08-06 00:12:57.999999900Z' will
both fail where for example
'1999-01-12 21:08:33.991259510Z' work correctly. I am not concerned about
the rounding inherent in the datatype.

More generally, even
SELECT '1999-08-06 00:12:57.9999999Z'::timestamp with time zone; will throw
the same error, so it seems to be something in the way Postgres
rounds/truncates the field.

Re: BUG #4789: ERROR 22008 on timestamp import

От
Tom Lane
Дата:
"Robert Kruuus" <robert.kruus@gov.sk.ca> writes:
> More generally, even
> SELECT '1999-08-06 00:12:57.9999999Z'::timestamp with time zone; will throw
> the same error, so it seems to be something in the way Postgres
> rounds/truncates the field.

Hmph.  Is your installation built with --enable-integer-datetimes?
(Try "show integer_datetimes;" if you're not sure.)

On my devel machine, I get this in 8.3

regression=# select '1999-08-06 00:12:57.999999900Z'::timestamptz;
      timestamptz
------------------------
 1999-08-05 20:12:58-04
(1 row)

and this in 8.4

regression=# select '1999-08-06 00:12:57.999999900Z'::timestamptz;
ERROR:  date/time field value out of range: "1999-08-06 00:12:57.999999900Z"
LINE 1: select '1999-08-06 00:12:57.999999900Z'::timestamptz;
               ^

but I bet it's the change in the default integer_datetimes setting
that is the relevant difference.

            regards, tom lane

Re: BUG #4789: ERROR 22008 on timestamp import

От
"Kevin Grittner"
Дата:
>>> Tom Lane <tgl@sss.pgh.pa.us> wrote:
> but I bet it's the change in the default integer_datetimes setting
> that is the relevant difference.

Confirmed.

cc=> select '1999-08-06 00:12:57.999999900Z'::timestamptz;
ERROR:  date/time field value out of range: "1999-08-06
00:12:57.999999900Z"
cc=> select version();
                                               version
-----------------------------------------------------------------------------------------------------
 PostgreSQL 8.3.5 on x86_64-unknown-linux-gnu, compiled by GCC gcc
(GCC) 4.1.2 20070115 (SUSE Linux)
(1 row)

cc=> show integer_datetimes ;
 integer_datetimes
-------------------
 on
(1 row)

-Kevin

Re: BUG #4789: ERROR 22008 on timestamp import

От
Tom Lane
Дата:
"Kruus, Robert ENV" <Robert.Kruus@gov.sk.ca> writes:
>> Hmph.  Is your installation built with --enable-integer-datetimes?

> Yes it is 'on'.

On further probing, I can make it happen with float datetimes too,
if I throw enough fractional nines in there:

regression=# select '1999-08-06 00:12:57.999999999999999999999999999900'::timestamptz;
ERROR:  date/time field value out of range: "1999-08-06 00:12:57.999999999999999999999999999900"

The problem seems to be here:

    /* do a sanity check */
#ifdef HAVE_INT64_TIMESTAMP
    if (tm->tm_hour < 0 || tm->tm_min < 0 || tm->tm_min > 59 ||
        tm->tm_sec < 0 || tm->tm_sec > 60 || *fsec < INT64CONST(0) ||
        *fsec >= USECS_PER_SEC)
        return DTERR_FIELD_OVERFLOW;
#else
    if (tm->tm_hour < 0 || tm->tm_min < 0 || tm->tm_min > 59 ||
        tm->tm_sec < 0 || tm->tm_sec > 60 || *fsec < 0 || *fsec >= 1)
        return DTERR_FIELD_OVERFLOW;
#endif

With enough nines, the fsec value is going to round up to 1.0 (float
case) or USECS_PER_SEC (int case).  So I think that this check ought
to allow, not exclude, the boundary value.  And then we need to be
sure the subsequent code adds the values together properly, but that
probably happens okay already.

            regards, tom lane

Re: BUG #4789: ERROR 22008 on timestamp import

От
Tom Lane
Дата:
I wrote:
> With enough nines, the fsec value is going to round up to 1.0 (float
> case) or USECS_PER_SEC (int case).  So I think that this check ought
> to allow, not exclude, the boundary value.

Patch applied here:
http://archives.postgresql.org/message-id/20090501192913.C39EC75407B@cvs.postgresql.org

            regards, tom lane