]> granicus.if.org Git - postgresql/commitdiff
Fix bugs in interval-to-time conversion: HAVE_INT64_TIMESTAMP case did not
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 16 Jun 2003 18:56:53 +0000 (18:56 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 16 Jun 2003 18:56:53 +0000 (18:56 +0000)
work at all, and neither case behaved sanely for negative intervals.

src/backend/utils/adt/date.c

index b3839a34da270b78e96934a5b9b03d0251f8b3df..1bcd6726aead879ff48cde8206da39e73176f11b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.73.2.4 2003/02/13 17:04:24 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.73.2.5 2003/06/16 18:56:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -999,6 +999,11 @@ time_interval(PG_FUNCTION_ARGS)
 
 /* interval_time()
  * Convert interval to time data type.
+ *
+ * This is defined as producing the fractional-day portion of the interval.
+ * Therefore, we can just ignore the months field.  It is not real clear
+ * what to do with negative intervals, but we choose to subtract the floor,
+ * so that, say, '-2 hours' becomes '22:00:00'.
  */
 Datum
 interval_time(PG_FUNCTION_ARGS)
@@ -1007,15 +1012,23 @@ interval_time(PG_FUNCTION_ARGS)
        TimeADT         result;
 
 #ifdef HAVE_INT64_TIMESTAMP
+       int64           days;
+
        result = span->time;
-       if ((result >= INT64CONST(86400000000))
-               || (result <= INT64CONST(-86400000000)))
-               result -= (result / INT64CONST(1000000) * INT64CONST(1000000));
+       if (result >= INT64CONST(86400000000))
+       {
+               days = result / INT64CONST(86400000000);
+               result -= days * INT64CONST(86400000000);
+       }
+       else if (result < 0)
+       {
+               days = (-result + INT64CONST(86400000000-1)) / INT64CONST(86400000000);
+               result += days * INT64CONST(86400000000);
+       }
 #else
-       Interval        span1;
-
        result = span->time;
-       TMODULO(result, span1.time, 86400e0);
+       if (result >= 86400e0 || result < 0)
+               result -= floor(result / 86400e0) * 86400e0;
 #endif
 
        PG_RETURN_TIMEADT(result);