Philipp Reisner <[EMAIL PROTECTED]> writes:
>                         strncpy(fstr, (cp + 1), 7);
> +                       fstr[7]=0;
>                         strcpy((fstr + strlen(fstr)), "000000");

After some looking around, it turns out there was another similar error,
plus several related places where the code was not quite right.
Attached is the full patch I applied against 7.3.4.  Many thanks for
pointing out this mistake!

                        regards, tom lane

Index: datetime.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/adt/datetime.c,v
retrieving revision 1.96.2.5
diff -c -r1.96.2.5 datetime.c
*** datetime.c  4 May 2003 04:30:35 -0000       1.96.2.5
--- datetime.c  5 Aug 2003 17:34:48 -0000
***************
*** 1128,1134 ****
                                                                if (*cp != '\0')
                                                                        return -1;
  #ifdef HAVE_INT64_TIMESTAMP
!                                                               *fsec = frac * 1000000;
  #else
                                                                *fsec = frac;
  #endif
--- 1128,1134 ----
                                                                if (*cp != '\0')
                                                                        return -1;
  #ifdef HAVE_INT64_TIMESTAMP
!                                                               *fsec = rint(frac * 
1000000);
  #else
                                                                *fsec = frac;
  #endif
***************
*** 1158,1166 ****
  
                                                                tmask |= DTK_TIME_M;
  #ifdef HAVE_INT64_TIMESTAMP
!                                                               dt2time((time * 
86400000000), &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
  #else
!                                                               dt2time((time * 
86400), &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
  #endif
                                                        }
                                                        break;
--- 1158,1168 ----
  
                                                                tmask |= DTK_TIME_M;
  #ifdef HAVE_INT64_TIMESTAMP
!                                                               dt2time((time * 
86400000000),
!                                                                               
&tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
  #else
!                                                               dt2time((time * 86400),
!                                                                               
&tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
  #endif
                                                        }
                                                        break;
***************
*** 1835,1843 ****
                                                        tmask = DTK_M(SECOND);
                                                        if (*cp == '.')
                                                        {
!                                                               *fsec = strtod(cp, 
&cp);
                                                                if (*cp != '\0')
                                                                        return -1;
                                                        }
                                                        break;
  
--- 1837,1852 ----
                                                        tmask = DTK_M(SECOND);
                                                        if (*cp == '.')
                                                        {
!                                                               double          frac;
! 
!                                                               frac = strtod(cp, &cp);
                                                                if (*cp != '\0')
                                                                        return -1;
+ #ifdef HAVE_INT64_TIMESTAMP
+                                                               *fsec = rint(frac * 
1000000);
+ #else
+                                                               *fsec = frac;
+ #endif
                                                        }
                                                        break;
  
***************
*** 1863,1871 ****
  
                                                                tmask |= DTK_TIME_M;
  #ifdef HAVE_INT64_TIMESTAMP
!                                                               dt2time((time * 
86400000000), &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
  #else
!                                                               dt2time((time * 
86400), &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
  #endif
                                                        }
                                                        break;
--- 1872,1882 ----
  
                                                                tmask |= DTK_TIME_M;
  #ifdef HAVE_INT64_TIMESTAMP
!                                                               dt2time((time * 
86400000000),
!                                                                               
&tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
  #else
!                                                               dt2time((time * 86400),
!                                                                               
&tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
  #endif
                                                        }
                                                        break;
***************
*** 2268,2291 ****
                        *fsec = 0;
                else if (*cp == '.')
                {
! #ifdef HAVE_INT64_TIMESTAMP
!                       char            fstr[MAXDATELEN + 1];
  
-                       /*
-                        * OK, we have at most six digits to work with. Let's
-                        * construct a string and then do the conversion to an
-                        * integer.
-                        */
-                       strncpy(fstr, (cp + 1), 7);
-                       strcpy((fstr + strlen(fstr)), "000000");
-                       *(fstr + 6) = '\0';
-                       *fsec = strtol(fstr, &cp, 10);
- #else
                        str = cp;
!                       *fsec = strtod(str, &cp);
! #endif
                        if (*cp != '\0')
                                return -1;
                }
                else
                        return -1;
--- 2279,2295 ----
                        *fsec = 0;
                else if (*cp == '.')
                {
!                       double          frac;
  
                        str = cp;
!                       frac = strtod(str, &cp);
                        if (*cp != '\0')
                                return -1;
+ #ifdef HAVE_INT64_TIMESTAMP
+                       *fsec = rint(frac * 1000000);
+ #else
+                       *fsec = frac;
+ #endif
                }
                else
                        return -1;
***************
*** 2328,2333 ****
--- 2332,2339 ----
  
        if (*cp == '.')
        {
+               double  frac;
+ 
                /*
                 * More than two digits? Then could be a date or a run-together
                 * time: 2001.360 20011225 040506.789
***************
*** 2336,2344 ****
                        return DecodeNumberField(flen, str, (fmask | DTK_DATE_M),
                                                                         tmask, tm, 
fsec, is2digits);
  
!               *fsec = strtod(cp, &cp);
                if (*cp != '\0')
                        return -1;
        }
        else if (*cp != '\0')
                return -1;
--- 2342,2355 ----
                        return DecodeNumberField(flen, str, (fmask | DTK_DATE_M),
                                                                         tmask, tm, 
fsec, is2digits);
  
!               frac = strtod(cp, &cp);
                if (*cp != '\0')
                        return -1;
+ #ifdef HAVE_INT64_TIMESTAMP
+               *fsec = rint(frac * 1000000);
+ #else
+               *fsec = frac;
+ #endif
        }
        else if (*cp != '\0')
                return -1;
***************
*** 2441,2459 ****
         */
        if ((cp = strchr(str, '.')) != NULL)
        {
! #ifdef HAVE_INT64_TIMESTAMP
!               char            fstr[MAXDATELEN + 1];
  
!               /*
!                * OK, we have at most six digits to care about. Let's construct a
!                * string and then do the conversion to an integer.
!                */
!               strcpy(fstr, (cp + 1));
!               strcpy((fstr + strlen(fstr)), "000000");
!               *(fstr + 6) = '\0';
!               *fsec = strtol(fstr, NULL, 10);
  #else
!               *fsec = strtod(cp, NULL);
  #endif
                *cp = '\0';
                len = strlen(str);
--- 2452,2464 ----
         */
        if ((cp = strchr(str, '.')) != NULL)
        {
!               double          frac;
  
!               frac = strtod(cp, NULL);
! #ifdef HAVE_INT64_TIMESTAMP
!               *fsec = rint(frac * 1000000);
  #else
!               *fsec = frac;
  #endif
                *cp = '\0';
                len = strlen(str);

---------------------------(end of broadcast)---------------------------
TIP 2: you can get off all lists at once with the unregister command
    (send "unregister YourEmailAddressHere" to [EMAIL PROTECTED])

Reply via email to