• Tom Lane's avatar
    Fix interval_transform so it doesn't throw away non-no-op casts. · f0774abd
    Tom Lane authored
    interval_transform() contained two separate bugs that caused it to
    sometimes mistakenly decide that a cast from interval to restricted
    interval is a no-op and throw it away.
    
    First, it was wrong to rely on dt.h's field type macros to have an
    ordering consistent with the field's significance; in one case they do
    not.  This led to mistakenly treating YEAR as less significant than MONTH,
    so that a cast from INTERVAL MONTH to INTERVAL YEAR was incorrectly
    discarded.
    
    Second, fls(1<<k) produces k+1 not k, so comparing its output directly
    to SECOND was wrong.  This led to supposing that a cast to INTERVAL
    MINUTE was really a cast to INTERVAL SECOND and so could be discarded.
    
    To fix, get rid of the use of fls(), and make a function based on
    intervaltypmodout to produce a field ID code adapted to the need here.
    
    Per bug #14479 from Piotr Stefaniak.  Back-patch to 9.2 where transform
    functions were introduced, because this code was born broken.
    
    Discussion: https://postgr.es/m/20161227172307.10135.7747@wrigleys.postgresql.org
    f0774abd
timestamp.c 141 KB