Improve interval_transform function to detect a few more cases.
authorRobert Haas <rhaas@postgresql.org>
Thu, 9 Feb 2012 17:21:57 +0000 (12:21 -0500)
committerRobert Haas <rhaas@postgresql.org>
Thu, 9 Feb 2012 17:24:22 +0000 (12:24 -0500)
Noah Misch, per a review comment from me.

src/backend/utils/adt/timestamp.c

index 44a3a922ece61f3bbb86236c0497a1bc87e3c21b..12af7f69f69051bf467e6b51f84e85ae7e323690 100644 (file)
@@ -958,6 +958,7 @@ interval_transform(PG_FUNCTION_ARGS)
        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,12 +975,16 @@ 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.
+        * 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 >= fls(old_range)) &&
-            (new_precis >= MAX_INTERVAL_PRECISION ||
+             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);
    }