On Wed, Feb 08, 2012 at 09:37:01AM -0500, Robert Haas wrote:
> On Tue, Feb 7, 2012 at 12:43 PM, Robert Haas <[email protected]> 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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers