• Tom Lane's avatar
    Clarify behavior of adding and altering a column in same ALTER command. · 9b9c5f27
    Tom Lane authored
    The behavior of something like
    
    ALTER TABLE transactions
      ADD COLUMN status varchar(30) DEFAULT 'old',
      ALTER COLUMN status SET default 'current';
    
    is to fill existing table rows with 'old', not 'current'.  That's
    intentional and desirable for a couple of reasons:
    
    * It makes the behavior the same whether you merge the sub-commands
    into one ALTER command or give them separately;
    
    * If we applied the new default while filling the table, there would
    be no way to get the existing behavior in one SQL command.
    
    The same reasoning applies in cases that add a column and then
    manipulate its GENERATED/IDENTITY status in a second sub-command,
    since the generation expression is really just a kind of default.
    However, that wasn't very obvious (at least not to me; earlier in
    the referenced discussion thread I'd thought it was a bug to be
    fixed).  And it certainly wasn't documented.
    
    Hence, add documentation, code comments, and a test case to clarify
    that this behavior is all intentional.
    
    In passing, adjust ATExecAddColumn's defaults-related relkind check
    so that it matches up exactly with ATRewriteTables, instead of being
    effectively (though not literally) the negated inverse condition.
    The reasoning can be explained a lot more concisely that way, too
    (not to mention that the comment now matches the code, which it
    did not before).
    
    Discussion: https://postgr.es/m/10365.1558909428@sss.pgh.pa.us
    9b9c5f27
identity.sql 9.03 KB