From 2613b7478573c7fc833c90ff8aa731a15d32aaaf Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu, 25 Aug 2005 05:01:43 +0000
Subject: [PATCH] Factor out the common subexpression month_remainder *
 DAYS_PER_MONTH in interval_mul and interval_div.  This avoids an optimization
 bug in A Certain Company's compiler (and given their explanation, I wouldn't
 be surprised if other compilers blow it too).  Besides the code seems more
 clear this way --- in the original formulation, you had to mentally recognize
 the common subexpression in order to understand what was going on.

---
 src/backend/utils/adt/timestamp.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index c218422a79..2b15e64e06 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.150 2005/08/25 03:53:22 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.151 2005/08/25 05:01:43 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2262,7 +2262,7 @@ interval_mul(PG_FUNCTION_ARGS)
 {
 	Interval   *span = PG_GETARG_INTERVAL_P(0);
 	float8		factor = PG_GETARG_FLOAT8(1);
-	double		month_remainder, day_remainder;
+	double		month_remainder, day_remainder, month_remainder_days;
 	Interval   *result;
 
 	result = (Interval *) palloc(sizeof(Interval));
@@ -2276,17 +2276,15 @@ interval_mul(PG_FUNCTION_ARGS)
 
 	/* Cascade fractions to lower units */
 	/* fractional months full days into days */
-	result->day += month_remainder * DAYS_PER_MONTH;
+	month_remainder_days = month_remainder * DAYS_PER_MONTH;
+	result->day += month_remainder_days;
 	/* fractional months partial days into time */
-	day_remainder += (month_remainder * DAYS_PER_MONTH) -
-					 (int)(month_remainder * DAYS_PER_MONTH);
+	day_remainder += month_remainder_days - (int) month_remainder_days;
 
 #ifdef HAVE_INT64_TIMESTAMP
-	result->time = rint(span->time * factor +
-					day_remainder * USECS_PER_DAY);
+	result->time = rint(span->time * factor + day_remainder * USECS_PER_DAY);
 #else
-	result->time = JROUND(span->time * factor +
-					day_remainder * SECS_PER_DAY);
+	result->time = JROUND(span->time * factor + day_remainder * SECS_PER_DAY);
 #endif
 
 	result = DatumGetIntervalP(DirectFunctionCall1(interval_justify_hours,
@@ -2309,7 +2307,7 @@ interval_div(PG_FUNCTION_ARGS)
 {
 	Interval   *span = PG_GETARG_INTERVAL_P(0);
 	float8		factor = PG_GETARG_FLOAT8(1);
-	double		month_remainder, day_remainder;
+	double		month_remainder, day_remainder, month_remainder_days;
 	Interval   *result;
 
 	result = (Interval *) palloc(sizeof(Interval));
@@ -2329,10 +2327,10 @@ interval_div(PG_FUNCTION_ARGS)
 
 	/* Cascade fractions to lower units */
 	/* fractional months full days into days */
-	result->day += month_remainder * DAYS_PER_MONTH;
+	month_remainder_days = month_remainder * DAYS_PER_MONTH;
+	result->day += month_remainder_days;
 	/* fractional months partial days into time */
-	day_remainder += (month_remainder * DAYS_PER_MONTH) -
-					 (int)(month_remainder * DAYS_PER_MONTH);
+	day_remainder += month_remainder_days - (int) month_remainder_days;
 
 #ifdef HAVE_INT64_TIMESTAMP
 	result->time += rint(day_remainder * USECS_PER_DAY);