From 7b70d0a2c970f94c754d3b7729a87120e7c47101 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 29 Jul 2009 22:19:23 +0000 Subject: [PATCH] Fix time_part and timetz_part (ie, EXTRACT() for those datatypes) to include a fractional part in the output for MILLISECOND and SECOND cases, rather than truncating the source value. This is what the float-timestamp code has always done, and it was clearly the code author's intent to do the same for integer timestamps, but he forgot about integer division in C. The other datatypes supported by EXTRACT() already do this correctly. Backpatch to 8.4, so that the default (integer) behavior of that branch will match the default (float) behavior of older branches. Arguably we should patch further back, but it's possible that applications are expecting the broken behavior in older branches. 8.4 is new enough that expectations shouldn't be too settled. Per report from Greg Stark. --- src/backend/utils/adt/date.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c index 43148bec90..99448375ec 100644 --- a/src/backend/utils/adt/date.c +++ b/src/backend/utils/adt/date.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.146 2009/06/11 14:49:03 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.146.2.1 2009/07/29 22:19:23 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1701,7 +1701,7 @@ time_part(PG_FUNCTION_ARGS) { case DTK_MICROSEC: #ifdef HAVE_INT64_TIMESTAMP - result = tm->tm_sec * USECS_PER_SEC + fsec; + result = tm->tm_sec * 1000000.0 + fsec; #else result = (tm->tm_sec + fsec) * 1000000; #endif @@ -1709,7 +1709,7 @@ time_part(PG_FUNCTION_ARGS) case DTK_MILLISEC: #ifdef HAVE_INT64_TIMESTAMP - result = tm->tm_sec * INT64CONST(1000) + fsec / INT64CONST(1000); + result = tm->tm_sec * 1000.0 + fsec / 1000.0; #else result = (tm->tm_sec + fsec) * 1000; #endif @@ -1717,7 +1717,7 @@ time_part(PG_FUNCTION_ARGS) case DTK_SECOND: #ifdef HAVE_INT64_TIMESTAMP - result = tm->tm_sec + fsec / USECS_PER_SEC; + result = tm->tm_sec + fsec / 1000000.0; #else result = tm->tm_sec + fsec; #endif @@ -2469,7 +2469,7 @@ timetz_part(PG_FUNCTION_ARGS) case DTK_MICROSEC: #ifdef HAVE_INT64_TIMESTAMP - result = tm->tm_sec * USECS_PER_SEC + fsec; + result = tm->tm_sec * 1000000.0 + fsec; #else result = (tm->tm_sec + fsec) * 1000000; #endif @@ -2477,7 +2477,7 @@ timetz_part(PG_FUNCTION_ARGS) case DTK_MILLISEC: #ifdef HAVE_INT64_TIMESTAMP - result = tm->tm_sec * INT64CONST(1000) + fsec / INT64CONST(1000); + result = tm->tm_sec * 1000.0 + fsec / 1000.0; #else result = (tm->tm_sec + fsec) * 1000; #endif @@ -2485,7 +2485,7 @@ timetz_part(PG_FUNCTION_ARGS) case DTK_SECOND: #ifdef HAVE_INT64_TIMESTAMP - result = tm->tm_sec + fsec / USECS_PER_SEC; + result = tm->tm_sec + fsec / 1000000.0; #else result = tm->tm_sec + fsec; #endif -- 2.50.1