On Wed, Feb 08, 2012 at 09:37:01AM -0500, Robert Haas wrote:
> On Tue, Feb 7, 2012 at 12:43 PM, Robert Haas <robertmh...@gmail.com> wrote:
> > I've committed the numeric and varbit patches and will look at the
> > temporal one next.
> 
> Committed, after changing the OIDs so they don't conflict.
> 
> Here's one more case for you to ponder:
> 
> rhaas=# create table noah (i interval day);
> CREATE TABLE
> rhaas=# alter table noah alter column i set data type interval second(3);
> DEBUG:  rewriting table "noah"
> ALTER TABLE
> 
> Do we really need a rewrite in that case?  The code acts like the
> interval range and precision are separate beasts, but is that really
> true?

The code has a thinko; a given interval typmod ultimately implies a single
point from which we truncate rightward.  The precision only matters if the
range covers SECOND.  Thanks; the attached patch improves this.
*** a/src/backend/utils/adt/timestamp.c
--- b/src/backend/utils/adt/timestamp.c
***************
*** 958,963 **** interval_transform(PG_FUNCTION_ARGS)
--- 958,964 ----
                int                     new_range = INTERVAL_RANGE(new_typmod);
                int                     new_precis = 
INTERVAL_PRECISION(new_typmod);
                int                     new_range_fls;
+               int                     old_range_fls;
  
                if (old_typmod == -1)
                {
***************
*** 974,985 **** interval_transform(PG_FUNCTION_ARGS)
                 * Temporally-smaller fields occupy higher positions in the 
range
                 * bitmap.  Since only the temporally-smallest bit matters for 
length
                 * coercion purposes, we compare the last-set bits in the 
ranges.
                 */
                new_range_fls = fls(new_range);
                if (new_typmod == -1 ||
                        ((new_range_fls >= SECOND ||
!                         new_range_fls >= fls(old_range)) &&
!                        (new_precis >= MAX_INTERVAL_PRECISION ||
                          new_precis >= old_precis)))
                        ret = relabel_to_typmod(source, new_typmod);
        }
--- 975,990 ----
                 * Temporally-smaller fields occupy higher positions in the 
range
                 * bitmap.  Since only the temporally-smallest bit matters for 
length
                 * coercion purposes, we compare the last-set bits in the 
ranges.
+                * Precision, which is to say, sub-second precision, only 
affects
+                * ranges that include SECOND.
                 */
                new_range_fls = fls(new_range);
+               old_range_fls = fls(old_range);
                if (new_typmod == -1 ||
                        ((new_range_fls >= SECOND ||
!                         new_range_fls >= old_range_fls) &&
!                        (old_range_fls < SECOND ||
!                         new_precis >= MAX_INTERVAL_PRECISION ||
                          new_precis >= old_precis)))
                        ret = relabel_to_typmod(source, new_typmod);
        }
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to