diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2006-09-04 01:26:28 +0000 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2006-09-04 01:26:28 +0000 |
| commit | 57bfb27e60055c10e42b87e68a894720c2f78e70 (patch) | |
| tree | ae27e5eb9686177b0668385abe023a169e656227 /src/interfaces/ecpg | |
| parent | 091fe037757abbecd6994daea0ae4eaa87f7217e (diff) | |
| download | postgresql-57bfb27e60055c10e42b87e68a894720c2f78e70.tar.gz | |
Fix interval input parser so that fractional weeks and months are
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
Diffstat (limited to 'src/interfaces/ecpg')
| -rw-r--r-- | src/interfaces/ecpg/pgtypeslib/interval.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/src/interfaces/ecpg/pgtypeslib/interval.c b/src/interfaces/ecpg/pgtypeslib/interval.c index b6d9b19b64..22643dbd96 100644 --- a/src/interfaces/ecpg/pgtypeslib/interval.c +++ b/src/interfaces/ecpg/pgtypeslib/interval.c @@ -1,4 +1,4 @@ -/* $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; |
