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