cascaded first to days and only what is leftover into seconds. This
seems to satisfy the principle of least surprise given the general
conversion to three-part interval values --- it was an oversight that
these cases weren't dealt with in 8.1. Michael Glaesemann
index f4aceed0aa3fad85b14e3e7c90e6142586318c14..ab0a3b4e89e27143d11081d424c957d3aa0d6fa3 100644 (file)
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.169 2006年07月25日 03:51:21 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.170 2006年09月04日 01:26:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2920,16 +2920,23 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct pg_tm * tm,
tm->tm_mday += val * 7;
if (fval != 0)
{
- int sec;
-
- fval *= 7 * SECS_PER_DAY;
- sec = fval;
- tm->tm_sec += sec;
+ int extra_days;
+ fval *= 7;
+ extra_days = (int32) fval;
+ tm->tm_mday += extra_days;
+ fval -= extra_days;
+ if (fval != 0)
+ {
+ int sec;
+ fval *= SECS_PER_DAY;
+ sec = fval;
+ tm->tm_sec += sec;
#ifdef HAVE_INT64_TIMESTAMP
- *fsec += (fval - sec) * 1000000;
+ *fsec += (fval - sec) * 1000000;
#else
- *fsec += fval - sec;
+ *fsec += fval - sec;
#endif
+ }
}
tmask = (fmask & DTK_M(DAY)) ? 0 : DTK_M(DAY);
break;
@@ -2938,16 +2945,23 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct pg_tm * tm,
tm->tm_mon += val;
if (fval != 0)
{
- int sec;
-
- fval *= DAYS_PER_MONTH * SECS_PER_DAY;
- sec = fval;
- tm->tm_sec += sec;
+ int day;
+ fval *= DAYS_PER_MONTH;
+ day = fval;
+ tm->tm_mday += day;
+ fval -= day;
+ if (fval != 0)
+ {
+ int sec;
+ fval *= SECS_PER_DAY;
+ sec = fval;
+ tm->tm_sec += sec;
#ifdef HAVE_INT64_TIMESTAMP
- *fsec += (fval - sec) * 1000000;
+ *fsec += (fval - sec) * 1000000;
#else
- *fsec += fval - sec;
+ *fsec += fval - sec;
#endif
+ }
}
tmask = DTK_M(MONTH);
break;
index b6d9b19b645d6b355542f0d035867f21e629b819..22643dbd966d114cea02c2c42a163ef60ed8debd 100644 (file)
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/interval.c,v 1.32 2006年06月06日 11:31:55 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/interval.c,v 1.33 2006年09月04日 01:26:28 tgl Exp $ */
#include "postgres_fe.h"
#include <time.h>
@@ -307,16 +307,23 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm * tm, fse
tm->tm_mday += val * 7;
if (fval != 0)
{
- int sec;
-
- fval *= 7 * SECS_PER_DAY;
- sec = fval;
- tm->tm_sec += sec;
+ int extra_days;
+ fval *= 7;
+ extra_days = (int32) fval;
+ tm->tm_mday += extra_days;
+ fval -= extra_days;
+ if (fval != 0)
+ {
+ int sec;
+ fval *= SECS_PER_DAY;
+ sec = fval;
+ tm->tm_sec += sec;
#ifdef HAVE_INT64_TIMESTAMP
- *fsec += (fval - sec) * 1000000;
+ *fsec += (fval - sec) * 1000000;
#else
- *fsec += fval - sec;
+ *fsec += fval - sec;
#endif
+ }
}
tmask = (fmask & DTK_M(DAY)) ? 0 : DTK_M(DAY);
break;
@@ -325,16 +332,23 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm * tm, fse
tm->tm_mon += val;
if (fval != 0)
{
- int sec;
-
- fval *= DAYS_PER_MONTH * SECS_PER_DAY;
- sec = fval;
- tm->tm_sec += sec;
+ int day;
+ fval *= DAYS_PER_MONTH;
+ day = fval;
+ tm->tm_mday += day;
+ fval -= day;
+ if (fval != 0)
+ {
+ int sec;
+ fval *= SECS_PER_DAY;
+ sec = fval;
+ tm->tm_sec += sec;
#ifdef HAVE_INT64_TIMESTAMP
- *fsec += (fval - sec) * 1000000;
+ *fsec += (fval - sec) * 1000000;
#else
- *fsec += fval - sec;
+ *fsec += fval - sec;
#endif
+ }
}
tmask = DTK_M(MONTH);
break;
index 0adda4a981d26e5f05fb01183a1b9dab960d361d..3a5fb12cbc317e8039cdf78f67c6a9518048300f 100644 (file)
@@ -39,6 +39,18 @@ SELECT INTERVAL '-1 days +02:03' AS "22 hours ago...";
-1 days +02:03:00
(1 row)
+SELECT INTERVAL '1.5 weeks' AS "Ten days twelve hours";
+ Ten days twelve hours
+-----------------------
+ 10 days 12:00:00
+(1 row)
+
+SELECT INTERVAL '1.5 months' AS "One month 15 days";
+ One month 15 days
+-------------------
+ 1 mon 15 days
+(1 row)
+
SELECT INTERVAL '10 years -11 month -12 days +13:14' AS "9 years...";
9 years...
----------------------------------
index bc384d012120441a155b6b8c4363e89849a3f50d..f38b01e45dc00a6d12c63a9eb1cd0b1dfbce80c8 100644 (file)
@@ -11,6 +11,8 @@ SELECT INTERVAL '-08:00' AS "Eight hours";
SELECT INTERVAL '-05' AS "Five hours";
SELECT INTERVAL '-1 +02:03' AS "22 hours ago...";
SELECT INTERVAL '-1 days +02:03' AS "22 hours ago...";
+SELECT INTERVAL '1.5 weeks' AS "Ten days twelve hours";
+SELECT INTERVAL '1.5 months' AS "One month 15 days";
SELECT INTERVAL '10 years -11 month -12 days +13:14' AS "9 years...";
CREATE TABLE INTERVAL_TBL (f1 interval);