Thread: BUG #13195: ALTER TABLE with DEFAULT NULL is different than implicit default
BUG #13195: ALTER TABLE with DEFAULT NULL is different than implicit default
From
autarch@urth.org
Date:
The following bug has been logged on the website: Bug reference: 13195 Logged by: Dave Rolsky Email address: autarch@urth.org PostgreSQL version: 9.2.10 Operating system: Linux Description: If I have a very large table (or set of partitioned tables) and run "ALTER TABLE foo ADD COLUMN bar text DEFAULT NULL", Pg takes several hours to complete this statement. If I simply remove the "DEFAULT NULL" clause, I will get what seems to be the exact same outcome in a fraction of a second. Ideally, the "DEFAULT NULL" would be optimized away. But maybe the two statements really are different in some way I can't see, in which case it'd be great if Pg could detect this case and warn that this will take forever with a suggestion that you can drop the "DEFAULT NULL (see X documentation)." Cheers, -dave
Re: BUG #13195: ALTER TABLE with DEFAULT NULL is different than implicit default
From
David Rowley
Date:
On 30 April 2015 at 04:56, <autarch@urth.org> wrote: > If I have a very large table (or set of partitioned tables) and run "ALTER > TABLE foo ADD COLUMN bar text DEFAULT NULL", Pg takes several hours to > complete this statement. If I simply remove the "DEFAULT NULL" clause, I > will get what seems to be the exact same outcome in a fraction of a second. > > Hi Dave, I'm not quite sure why you're seeing this, as from looking at the code it appears to optimise this properly. I've also tested with: david=# create table tt (id int not null); CREATE TABLE Time: 5.026 ms david=# insert into tt select x.x from generate_series(1,50000000)x(x); INSERT 0 50000000 Time: 130046.906 ms david=# alter table tt add column bar text default null; ALTER TABLE Time: 31.459 ms david=# alter table tt add column bar1 text; ALTER TABLE Time: 1.078 ms david=# alter table tt add column bar2 text default null; ALTER TABLE Time: 0.954 ms david=# select version(); version -------------------------------------------------------------- PostgreSQL 9.2.10, compiled by Visual C++ build 1700, 64-bit If you're actually testing with a domain type rather than a built in type, then I could see why you'd get the slow down. Try: david=# create domain mytexttype as text; CREATE DOMAIN Time: 1.408 ms david=# alter table tt add column bar5 mytexttype default null; ALTER TABLE Time: 34141.624 ms Notice it took 34 seconds that time. This is explained in the following code comment: * If there is no default, Phase 3 doesn't have to do anything, because * that effectively means that the default is NULL. The heap tuple access * routines always check for attnum > # of attributes in tuple, and return * NULL if so, so without any modification of the tuple data we will get * the effect of NULL values in the new column. * * An exception occurs when the new column is of a domain type: the domain * might have a NOT NULL constraint, or a check constraint that indirectly * rejects nulls. If there are any domain constraints then we construct * an explicit NULL default value that will be passed through * CoerceToDomain processing. (This is a tad inefficient, since it causes * rewriting the table which we really don't have to do, but the present * design of domain processing doesn't offer any simple way of checking * the constraints more directly.) Are you perhaps actually using a domain type and not text? Do you see the problem with my test case? Regards David Rowley