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])