Michael Glaesemann wrote:
> 
> On Aug 29, 2006, at 15:38 , Michael Glaesemann wrote:
> 
> > I think I've got it. I plan to update the regression tests this  
> > evening, but I wanted to post what I believe is a solution.
> 
> I've cleaned up the patch a bit in terms of whitespace, comments, and  
> parens. I've also updated the interval and horology regression tests.  
> The horology tests needed updating because I added 5 rows to  
> INTERVAL_TBL. I didn't check the math for every row of time(tz |  
> stamp | stamptz)/interval arithmetic in the horology tests as I think  
> problems in this area would have shown up before. Does that make  
> sense or it just rationalization on my part?
> 
> Both with and without --enable-integer-datetimes pass the regression  
> tests.

Uh, I came up with a cleaner one, I think.  I didn't test
--enable-integer-datetimes yet.

I tested a few of your examples:

        test=> select '41 mon 10:00:00'::interval / 10 as "pos";
                  pos
        ------------------------
         4 mons 3 days 01:00:00
        (1 row)

It basically rounds the remainders to full values if they are close to
full (+/- 0.000001).

-- 
  Bruce Momjian   [EMAIL PROTECTED]
  EnterpriseDB    http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +
Index: src/backend/utils/adt/timestamp.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v
retrieving revision 1.165
diff -c -c -r1.165 timestamp.c
*** src/backend/utils/adt/timestamp.c	13 Jul 2006 16:49:16 -0000	1.165
--- src/backend/utils/adt/timestamp.c	29 Aug 2006 16:06:49 -0000
***************
*** 2505,2510 ****
--- 2505,2513 ----
  	result->day = (int32) day_remainder;
  	month_remainder -= result->month;
  	day_remainder -= result->day;
+ 	if (day_remainder != (int32)day_remainder &&
+ 		TSROUND(day_remainder) == rint(day_remainder))
+ 		day_remainder = rint(day_remainder);
  
  	/*
  	 * The above correctly handles the whole-number part of the month and day
***************
*** 2518,2523 ****
--- 2521,2529 ----
  
  	/* fractional months full days into days */
  	month_remainder_days = month_remainder * DAYS_PER_MONTH;
+ 	if (month_remainder_days != (int32)month_remainder_days &&
+ 		TSROUND(month_remainder_days) == rint(month_remainder_days))
+ 		month_remainder_days = rint(month_remainder_days);
  	result->day += (int32) month_remainder_days;
  	/* fractional months partial days into time */
  	day_remainder += month_remainder_days - (int32) month_remainder_days;
***************
*** 2564,2569 ****
--- 2570,2578 ----
  	result->day = (int32) day_remainder;
  	month_remainder -= result->month;
  	day_remainder -= result->day;
+ 	if (day_remainder != (int32)day_remainder &&
+ 		TSROUND(day_remainder) == rint(day_remainder))
+ 		day_remainder = rint(day_remainder);
  
  	/*
  	 * Handle any fractional parts the same way as in interval_mul.
***************
*** 2571,2576 ****
--- 2580,2588 ----
  
  	/* fractional months full days into days */
  	month_remainder_days = month_remainder * DAYS_PER_MONTH;
+ 	if (month_remainder_days != (int32)month_remainder_days &&
+ 		TSROUND(month_remainder_days) == rint(month_remainder_days))
+ 		month_remainder_days = rint(month_remainder_days);
  	result->day += (int32) month_remainder_days;
  	/* fractional months partial days into time */
  	day_remainder += month_remainder_days - (int32) month_remainder_days;
---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend

Reply via email to