]> granicus.if.org Git - postgresql/commitdiff
Properly adjust age() seconds to match the sign of the larger units.
authorBruce Momjian <bruce@momjian.us>
Wed, 18 Jul 2007 03:13:13 +0000 (03:13 +0000)
committerBruce Momjian <bruce@momjian.us>
Wed, 18 Jul 2007 03:13:13 +0000 (03:13 +0000)
Patch from Tom.

src/backend/utils/adt/timestamp.c

index 04eaa81140d27baf27b2cf53e3aff95272e16a9e..73b8fbfa3084e5385e076c96780c5526f9492265 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.179 2007/07/06 04:15:59 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.180 2007/07/18 03:13:13 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3044,7 +3044,8 @@ timestamp_age(PG_FUNCTION_ARGS)
        if (timestamp2tm(dt1, NULL, tm1, &fsec1, NULL, NULL) == 0 &&
                timestamp2tm(dt2, NULL, tm2, &fsec2, NULL, NULL) == 0)
        {
-               fsec = (fsec1 - fsec2);
+               /* form the symbolic difference */
+               fsec = fsec1 - fsec2;
                tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
                tm->tm_min = tm1->tm_min - tm2->tm_min;
                tm->tm_hour = tm1->tm_hour - tm2->tm_hour;
@@ -3064,6 +3065,17 @@ timestamp_age(PG_FUNCTION_ARGS)
                        tm->tm_year = -tm->tm_year;
                }
 
+               /* propagate any negative fields into the next higher field */
+               while (fsec < 0)
+               {
+#ifdef HAVE_INT64_TIMESTAMP
+                       fsec += USECS_PER_SEC;
+#else
+                       fsec += 1.0;
+#endif
+                       tm->tm_sec--;
+               }
+
                while (tm->tm_sec < 0)
                {
                        tm->tm_sec += SECS_PER_MINUTE;
@@ -3158,6 +3170,7 @@ timestamptz_age(PG_FUNCTION_ARGS)
        if (timestamp2tm(dt1, &tz1, tm1, &fsec1, &tzn, NULL) == 0 &&
                timestamp2tm(dt2, &tz2, tm2, &fsec2, &tzn, NULL) == 0)
        {
+               /* form the symbolic difference */
                fsec = fsec1 - fsec2;
                tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
                tm->tm_min = tm1->tm_min - tm2->tm_min;
@@ -3178,6 +3191,17 @@ timestamptz_age(PG_FUNCTION_ARGS)
                        tm->tm_year = -tm->tm_year;
                }
 
+               /* propagate any negative fields into the next higher field */
+               while (fsec < 0)
+               {
+#ifdef HAVE_INT64_TIMESTAMP
+                       fsec += USECS_PER_SEC;
+#else
+                       fsec += 1.0;
+#endif
+                       tm->tm_sec--;
+               }
+
                while (tm->tm_sec < 0)
                {
                        tm->tm_sec += SECS_PER_MINUTE;