\set ncolumns 1000 \set nrows 400 \o /dev/null drop table if exists normal, missing, dropped; -- normal case, all attrs exist in the tuples select 'create table normal (' || string_agg('c'|| x::text || ' int',',') || ');' from generate_Series(1,:ncolumns) x; \gexec select 'insert into normal select ' || left(repeat('1,',:ncolumns),-1) || ' from generate_Series(1,' || :nrows || ') x;'; \gexec -- missing case. Table has all attrs missing create table missing(); INSERT INTO missing SELECT FROM generate_series(1,:nrows); select 'alter table missing ' || string_agg('add column c'||x::text || ' int default 1',',') || ';' from generate_Series(1,:ncolumns) x; \gexec -- first column dropped select 'create table dropped (' || string_agg('c'|| x::text || ' int',',') || ');' from generate_Series(0,:ncolumns) x; \gexec select 'insert into dropped select ' || left(repeat('1,',:ncolumns + 1),-1) || ' from generate_Series(1,' || :nrows || ') x;'; \gexec alter table dropped drop column c0; \o select relname,pg_relation_Size(oid) table_size_bytes from pg_class where relname in('normal','missing','dropped');