Re: [BUGS] BUG #1609: Bug in interval datatype for 64 Bit timestamps - Mailing list pgsql-patches
From | Bruce Momjian |
---|---|
Subject | Re: [BUGS] BUG #1609: Bug in interval datatype for 64 Bit timestamps |
Date | |
Msg-id | 200505240416.j4O4GcO18190@candle.pha.pa.us Whole thread Raw |
List | pgsql-patches |
Tom Lane wrote: > Oliver Siegmar <oliver@siegmar.net> writes: > > On Thursday 21 April 2005 15:57, Tom Lane wrote: > >> If it is only the float case, some imprecision is to be expected. > > > So everything is okay? > > Well, it's not necessarily *wrong*, but maybe we could improve it. > The code currently assumes it can print 10 fractional digits in the > float case, which is overly optimistic once you get a large number > of days in the "days" component. Maybe we should add some code > to back off the precision depending on the number of days? I decided to trim off just the last digit to show only 9 digits instead of 10. The logic is that the last digit is giving us problems, and 9 digits is nano-second resolution, while 10 is 100 picoseconds, which is kind of a weird default. It does fix the problem: test=> select '2005 years 4 mons 20 days 15 hours 57 mins 12.1 secs ago'::interval; interval ------------------------------------------- -2005 years -4 mons -20 days -15:57:12.10 (1 row) Doing like 200 days still shows the failure: test=> select '2005 years 4 mons 200 days 15 hours 57 mins 12.1 secs ago'::interval; interval --------------------------------------------------- -2005 years -4 mons -200 days -15:57:12.100000001 (1 row) but I figure 20 days is much more common than 200. -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073 Index: src/backend/utils/adt/datetime.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v retrieving revision 1.144 diff -c -c -r1.144 datetime.c *** src/backend/utils/adt/datetime.c 24 May 2005 02:09:45 -0000 1.144 --- src/backend/utils/adt/datetime.c 24 May 2005 04:11:57 -0000 *************** *** 3444,3450 **** #ifdef HAVE_INT64_TIMESTAMP sprintf(str + strlen(str), ":%02d.%06d", tm->tm_sec, fsec); #else ! sprintf(str + strlen(str), ":%013.10f", tm->tm_sec + fsec); #endif /* chop off trailing pairs of zeros... */ while (strcmp((str + strlen(str) - 2), "00") == 0 && --- 3444,3450 ---- #ifdef HAVE_INT64_TIMESTAMP sprintf(str + strlen(str), ":%02d.%06d", tm->tm_sec, fsec); #else ! sprintf(str + strlen(str), ":%012.9f", tm->tm_sec + fsec); #endif /* chop off trailing pairs of zeros... */ while (strcmp((str + strlen(str) - 2), "00") == 0 && *************** *** 3787,3793 **** sprintf(cp, ".%06d", Abs(fsec)); #else fsec += tm->tm_sec; ! sprintf(cp, ":%013.10f", fabs(fsec)); #endif TrimTrailingZeros(cp); cp += strlen(cp); --- 3787,3793 ---- sprintf(cp, ".%06d", Abs(fsec)); #else fsec += tm->tm_sec; ! sprintf(cp, ":%012.9f", fabs(fsec)); #endif TrimTrailingZeros(cp); cp += strlen(cp); Index: src/interfaces/ecpg/pgtypeslib/interval.c =================================================================== RCS file: /cvsroot/pgsql/src/interfaces/ecpg/pgtypeslib/interval.c,v retrieving revision 1.16 diff -c -c -r1.16 interval.c *** src/interfaces/ecpg/pgtypeslib/interval.c 24 May 2005 02:09:45 -0000 1.16 --- src/interfaces/ecpg/pgtypeslib/interval.c 24 May 2005 04:12:00 -0000 *************** *** 511,517 **** sprintf(cp, ".%06d", (fsec >= 0) ? fsec : -(fsec)); #else fsec += tm->tm_sec; ! sprintf(cp, ":%013.10f", fabs(fsec)); #endif TrimTrailingZeros(cp); cp += strlen(cp); --- 511,517 ---- sprintf(cp, ".%06d", (fsec >= 0) ? fsec : -(fsec)); #else fsec += tm->tm_sec; ! sprintf(cp, ":%012.9f", fabs(fsec)); #endif TrimTrailingZeros(cp); cp += strlen(cp);
pgsql-patches by date: