Tom Lane wrote:
> Oliver Siegmar <[EMAIL PROTECTED]> 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);
---------------------------(end of broadcast)---------------------------
TIP 8: explain analyze is your friend

Reply via email to