8000 Repair two recently reported problems: · rtpg/postgres@621e372 · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit 621e372

Browse files
author
Thomas G. Lockhart
committed
Repair two recently reported problems:
1) datetime_pl_span() added the seconds field before adding the months field. This lead to erroneous results for e.g. select datetime '1999-11-30' + timespan '1 mon - 1 sec'; Reverse the order of operations to add months first. 2) tm2timespan() did all intermediate math as integer, converting to double at the very end. This resulted in hidden overflows when given very large integer days, hours, etc. For example, select '74565 days'::timespan; produced the wrong result. Change code to ensure that doubles are used for intermediate calculations. Thanks to Olivier PRENANT <ohp@pyrenet.fr> and Tulassay Zsolt <zsolt@tek.bke.hu> for problem reports and to Tom Lane for accurate analyses.
1 parent 424ff56 commit 621e372

File tree

1 file changed

+12
-8
lines changed
  • src/backend/utils/adt

1 file changed

+12
-8
lines changed

src/backend/utils/adt/dt.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.72.2.1 1999/08/02 05:24:51 scrappy Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.72.2.2 2000/01/04 07:56:23 thomas Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -811,6 +811,7 @@ datetime_mi(DateTime *datetime1, DateTime *datetime2)
811811
* To add a month, increment the month, and use the same day of month.
812812
* Then, if the next month has fewer days, set the day of month
813813
* to the last day of month.
814+
* Lastly, add in the "quantitative time".
814815
*/
815816
DateTime *
816817
datetime_pl_span(DateTime *datetime, TimeSpan *span)
@@ -843,12 +844,6 @@ datetime_pl_span(DateTime *datetime, TimeSpan *span)
843844
{
844845
dt = (DATETIME_IS_RELATIVE(*datetime) ? SetDateTime(*datetime) : *datetime);
845846

846-
#ifdef ROUND_ALL
847-
dt = JROUND(dt + span->time);
848-
#else
849-
dt += span->time;
850-
#endif
851-
852847
if (span->month != 0)
853848
{
854849
struct tm tt,
@@ -889,6 +884,12 @@ datetime_pl_span(DateTime *datetime, TimeSpan *span)
889884
DATETIME_INVALID(dt);
890885
}
891886

887+
#ifdef ROUND_ALL
888+
dt = JROUND(dt + span->time);
889+
#else
890+
dt += span->time;
891+
#endif
892+
892893
*result = dt;
893894
}
894895

@@ -2569,7 +2570,10 @@ static int
25692570
tm2timespan(struct tm * tm, double fsec, TimeSpan *span)
25702571
{
25712572
span->month = ((tm->tm_year * 12) + tm->tm_mon);
2572-
span->time = ((((((tm->tm_mday * 24) + tm->tm_hour) * 60) + tm->tm_min) * 60) + tm->tm_sec);
2573+
span->time = ((((((tm->tm_mday * 24.0)
2574+
+ tm->tm_hour) * 60.0)
2575+
+ tm->tm_min) * 60.0)
2576+
+ tm->tm_sec);
25732577
span->time = JROUND(span->time + fsec);
25742578

25752579
#ifdef DATEDEBUG

0 commit comments

Comments
 (0)
0