1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-02 09:02:37 +03:00

ALTER TABLE DROP COLUMN works. Patch by Christopher Kings-Lynne,

code review by Tom Lane.  Remaining issues: functions that take or
return tuple types are likely to break if one drops (or adds!)
a column in the table defining the type.  Need to think about what
to do here.

Along the way: some code review for recent COPY changes; mark system
columns attnotnull = true where appropriate, per discussion a month ago.
This commit is contained in:
Tom Lane
2002-08-02 18:15:10 +00:00
parent 5e6528adf7
commit 38bb77a5d1
44 changed files with 1823 additions and 891 deletions

View File

@ -635,9 +635,9 @@ delete from atacc1;
alter table atacc1 alter test set not null;
-- try altering a non-existent column, should fail
alter table atacc1 alter bar set not null;
ERROR: ALTER TABLE: relation "atacc1" has no column "bar"
ERROR: Relation "atacc1" has no column "bar"
alter table atacc1 alter bar drop not null;
ERROR: ALTER TABLE: relation "atacc1" has no column "bar"
ERROR: Relation "atacc1" has no column "bar"
-- try altering the oid column, should fail
alter table atacc1 alter oid set not null;
ERROR: ALTER TABLE: Cannot alter system attribute "oid"
@ -707,7 +707,7 @@ ERROR: pg_atoi: error in "wrong_datatype": can't parse "wrong_datatype"
alter table def_test alter column c2 set default 20;
-- set defaults on a non-existent column: this should fail
alter table def_test alter column c3 set default 30;
ERROR: ALTER TABLE: relation "def_test" has no column "c3"
ERROR: Relation "def_test" has no column "c3"
-- set defaults on views: we need to create a view, add a rule
-- to allow insertions into it, and then alter the view to add
-- a default
@ -735,3 +735,291 @@ select * from def_view_test;
drop rule def_view_test_ins on def_view_test;
drop view def_view_test;
drop table def_test;
-- alter table / drop column tests
-- try altering system catalogs, should fail
alter table pg_class drop column relname;
ERROR: ALTER TABLE: relation "pg_class" is a system catalog
-- try altering non-existent table, should fail
alter table foo drop column bar;
ERROR: Relation "foo" does not exist
-- test dropping columns
create table atacc1 (a int4 not null, b int4, c int4 not null, d int4);
insert into atacc1 values (1, 2, 3, 4);
alter table atacc1 drop a;
alter table atacc1 drop a;
ERROR: Relation "atacc1" has no column "a"
-- SELECTs
select * from atacc1;
b | c | d
---+---+---
2 | 3 | 4
(1 row)
select * from atacc1 order by a;
ERROR: Attribute "a" not found
select * from atacc1 order by "........pg.dropped.1........";
ERROR: Attribute "........pg.dropped.1........" not found
select * from atacc1 group by a;
ERROR: Attribute "a" not found
select * from atacc1 group by "........pg.dropped.1........";
ERROR: Attribute "........pg.dropped.1........" not found
select atacc1.* from atacc1;
b | c | d
---+---+---
2 | 3 | 4
(1 row)
select a from atacc1;
ERROR: Attribute "a" not found
select atacc1.a from atacc1;
ERROR: No such attribute atacc1.a
select b,c,d from atacc1;
b | c | d
---+---+---
2 | 3 | 4
(1 row)
select a,b,c,d from atacc1;
ERROR: Attribute "a" not found
select * from atacc1 where a = 1;
ERROR: Attribute "a" not found
select "........pg.dropped.1........" from atacc1;
ERROR: Attribute "........pg.dropped.1........" not found
select atacc1."........pg.dropped.1........" from atacc1;
ERROR: No such attribute atacc1.........pg.dropped.1........
select "........pg.dropped.1........",b,c,d from atacc1;
ERROR: Attribute "........pg.dropped.1........" not found
select * from atacc1 where "........pg.dropped.1........" = 1;
ERROR: Attribute "........pg.dropped.1........" not found
-- UPDATEs
update atacc1 set a = 3;
ERROR: Relation "atacc1" has no column "a"
update atacc1 set b = 2 where a = 3;
ERROR: Attribute "a" not found
update atacc1 set "........pg.dropped.1........" = 3;
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
update atacc1 set b = 2 where "........pg.dropped.1........" = 3;
ERROR: Attribute "........pg.dropped.1........" not found
-- INSERTs
insert into atacc1 values (10, 11, 12, 13);
ERROR: INSERT has more expressions than target columns
insert into atacc1 values (default, 11, 12, 13);
ERROR: INSERT has more expressions than target columns
insert into atacc1 values (11, 12, 13);
insert into atacc1 (a) values (10);
ERROR: Relation "atacc1" has no column "a"
insert into atacc1 (a) values (default);
ERROR: Relation "atacc1" has no column "a"
insert into atacc1 (a,b,c,d) values (10,11,12,13);
ERROR: Relation "atacc1" has no column "a"
insert into atacc1 (a,b,c,d) values (default,11,12,13);
ERROR: Relation "atacc1" has no column "a"
insert into atacc1 (b,c,d) values (11,12,13);
insert into atacc1 ("........pg.dropped.1........") values (10);
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
insert into atacc1 ("........pg.dropped.1........") values (default);
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
insert into atacc1 ("........pg.dropped.1........",b,c,d) values (10,11,12,13);
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
insert into atacc1 ("........pg.dropped.1........",b,c,d) values (default,11,12,13);
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
-- DELETEs
delete from atacc1 where a = 3;
ERROR: Attribute "a" not found
delete from atacc1 where "........pg.dropped.1........" = 3;
ERROR: Attribute "........pg.dropped.1........" not found
delete from atacc1;
-- try dropping a non-existent column, should fail
alter table atacc1 drop bar;
ERROR: Relation "atacc1" has no column "bar"
-- try dropping the oid column, should fail
alter table atacc1 drop oid;
ERROR: ALTER TABLE: Cannot drop system attribute "oid"
-- try creating a view and altering that, should fail
create view myview as select * from atacc1;
select * from myview;
b | c | d
---+---+---
(0 rows)
alter table myview drop d;
ERROR: ALTER TABLE: relation "myview" is not a table
drop view myview;
-- test some commands to make sure they fail on the dropped column
analyze atacc1(a);
ERROR: Relation "atacc1" has no column "a"
analyze atacc1("........pg.dropped.1........");
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
vacuum analyze atacc1(a);
ERROR: Relation "atacc1" has no column "a"
vacuum analyze atacc1("........pg.dropped.1........");
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
comment on column atacc1.a is 'testing';
ERROR: Relation "atacc1" has no column "a"
comment on column atacc1."........pg.dropped.1........" is 'testing';
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
alter table atacc1 alter a set storage plain;
ERROR: ALTER TABLE: relation "atacc1" has no column "a"
alter table atacc1 alter "........pg.dropped.1........" set storage plain;
ERROR: ALTER TABLE: relation "atacc1" has no column "........pg.dropped.1........"
alter table atacc1 alter a set statistics 0;
ERROR: ALTER TABLE: relation "atacc1" has no column "a"
alter table atacc1 alter "........pg.dropped.1........" set statistics 0;
ERROR: ALTER TABLE: relation "atacc1" has no column "........pg.dropped.1........"
alter table atacc1 alter a set default 3;
ERROR: Relation "atacc1" has no column "a"
alter table atacc1 alter "........pg.dropped.1........" set default 3;
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
alter table atacc1 alter a drop default;
ERROR: Relation "atacc1" has no column "a"
alter table atacc1 alter "........pg.dropped.1........" drop default;
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
alter table atacc1 alter a set not null;
ERROR: Relation "atacc1" has no column "a"
alter table atacc1 alter "........pg.dropped.1........" set not null;
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
alter table atacc1 alter a drop not null;
ERROR: Relation "atacc1" has no column "a"
alter table atacc1 alter "........pg.dropped.1........" drop not null;
ERROR: Relation "atacc1" has no column "........pg.dropped.1........"
alter table atacc1 rename a to x;
ERROR: renameatt: attribute "a" does not exist
alter table atacc1 rename "........pg.dropped.1........" to x;
ERROR: renameatt: attribute "........pg.dropped.1........" does not exist
alter table atacc1 add primary key(a);
ERROR: ALTER TABLE: column "a" named in key does not exist
alter table atacc1 add primary key("........pg.dropped.1........");
ERROR: ALTER TABLE: column "........pg.dropped.1........" named in key does not exist
alter table atacc1 add unique(a);
ERROR: ALTER TABLE: column "a" named in key does not exist
alter table atacc1 add unique("........pg.dropped.1........");
ERROR: ALTER TABLE: column "........pg.dropped.1........" named in key does not exist
alter table atacc1 add check (a > 3);
ERROR: Attribute "a" not found
alter table atacc1 add check ("........pg.dropped.1........" > 3);
ERROR: Attribute "........pg.dropped.1........" not found
create table atacc2 (id int4 unique);
NOTICE: CREATE TABLE / UNIQUE will create implicit index 'atacc2_id_key' for table 'atacc2'
alter table atacc1 add foreign key (a) references atacc2(id);
NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
ERROR: ALTER TABLE: column "a" referenced in foreign key constraint does not exist
alter table atacc1 add foreign key ("........pg.dropped.1........") references atacc2(id);
NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
ERROR: ALTER TABLE: column "........pg.dropped.1........" referenced in foreign key constraint does not exist
alter table atacc2 add foreign key (id) references atacc1(a);
NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
ERROR: UNIQUE constraint matching given keys for referenced table "atacc1" not found
alter table atacc2 add foreign key (id) references atacc1("........pg.dropped.1........");
NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
ERROR: UNIQUE constraint matching given keys for referenced table "atacc1" not found
drop table atacc2;
create index "testing_idx" on atacc1(a);
ERROR: DefineIndex: attribute "a" not found
create index "testing_idx" on atacc1("........pg.dropped.1........");
ERROR: DefineIndex: attribute "........pg.dropped.1........" not found
-- test create as and select into
insert into atacc1 values (21, 22, 23);
create table test1 as select * from atacc1;
select * from test1;
b | c | d
----+----+----
21 | 22 | 23
(1 row)
drop table test1;
select * into test2 from atacc1;
select * from test2;
b | c | d
----+----+----
21 | 22 | 23
(1 row)
drop table test2;
-- try dropping all columns
alter table atacc1 drop c;
alter table atacc1 drop d;
alter table atacc1 drop b;
ERROR: ALTER TABLE: Cannot drop last column from table "atacc1"
select * from atacc1;
b
----
21
(1 row)
drop table atacc1;
-- test inheritance
create table parent (a int, b int, c int);
insert into parent values (1, 2, 3);
alter table parent drop a;
create table child (d varchar(255)) inherits (parent);
insert into child values (12, 13, 'testing');
select * from parent;
b | c
----+----
2 | 3
12 | 13
(2 rows)
select * from child;
b | c | d
----+----+---------
12 | 13 | testing
(1 row)
alter table parent drop c;
select * from parent;
b
----
2
12
(2 rows)
select * from child;
b | d
----+---------
12 | testing
(1 row)
drop table child;
drop table parent;
-- test copy in/out
create table test (a int4, b int4, c int4);
insert into test values (1,2,3);
alter table test drop a;
copy test to stdout;
2 3
copy test(a) to stdout;
ERROR: Relation "test" has no column "a"
copy test("........pg.dropped.1........") to stdout;
ERROR: Relation "test" has no column "........pg.dropped.1........"
copy test from stdin;
ERROR: copy: line 1, Extra data after last expected column
lost synchronization with server, resetting connection
select * from test;
b | c
---+---
2 | 3
(1 row)
copy test from stdin;
select * from test;
b | c
----+----
2 | 3
21 | 22
(2 rows)
copy test(a) from stdin;
ERROR: Relation "test" has no column "a"
copy test("........pg.dropped.1........") from stdin;
ERROR: Relation "test" has no column "........pg.dropped.1........"
copy test(b,c) from stdin;
select * from test;
b | c
----+----
2 | 3
21 | 22
31 | 32
(3 rows)
drop table test;

View File

@ -29,26 +29,44 @@ COPY x (b, d) from stdin;
COPY x (a, b, c, d, e) from stdin;
-- non-existent column in column list: should fail
COPY x (xyz) from stdin;
ERROR: COPY: Specified column "xyz" does not exist
ERROR: Relation "x" has no column "xyz"
-- too many columns in column list: should fail
COPY x (a, b, c, d, e, d, c) from stdin;
ERROR: COPY: Too many columns specified
ERROR: Attribute "d" specified more than once
-- missing data: should fail
COPY x from stdin;
ERROR: copy: line 1, COPY TEXT: Missing data for attribute 1
ERROR: copy: line 1, Missing data for column "b"
lost synchronization with server, resetting connection
COPY x from stdin;
ERROR: copy: line 1, COPY TEXT: Missing data for attribute 4
ERROR: copy: line 1, Missing data for column "e"
lost synchronization with server, resetting connection
COPY x from stdin;
ERROR: copy: line 1, COPY TEXT: Missing data for attribute 4
ERROR: copy: line 1, Missing data for column "e"
lost synchronization with server, resetting connection
-- extra data: should fail
COPY x from stdin;
ERROR: copy: line 1, COPY TEXT: Extra data encountered
ERROR: copy: line 1, Extra data after last expected column
lost synchronization with server, resetting connection
-- various COPY options: delimiters, oids, NULL string
COPY x (b, c, d, e) from stdin with oids delimiter ',' null 'x';
-- check results of copy in
SELECT * FROM x;
a | b | c | d | e
-------+----+-------+--------+----------------------
10000 | 21 | 31 | 41 | before trigger fired
10001 | 22 | 32 | 42 | before trigger fired
10002 | 23 | 33 | 43 | before trigger fired
10003 | 24 | 34 | 44 | before trigger fired
10004 | 25 | 35 | 45 | before trigger fired
10005 | 26 | 36 | 46 | before trigger fired
6 | | 45 | 80 | before trigger fired
1 | 1 | stuff | test_1 | after trigger fired
2 | 2 | stuff | test_2 | after trigger fired
3 | 3 | stuff | test_3 | after trigger fired
4 | 4 | stuff | test_4 | after trigger fired
5 | 5 | stuff | test_5 | after trigger fired
(12 rows)
-- COPY w/ oids on a table w/o oids should fail
CREATE TABLE no_oids (
a int,
@ -61,6 +79,7 @@ COPY no_oids FROM stdin WITH OIDS;
ERROR: COPY: table "no_oids" does not have OIDs
COPY no_oids TO stdout WITH OIDS;
ERROR: COPY: table "no_oids" does not have OIDs
-- check copy out
COPY x TO stdout;
10000 21 31 41 before trigger fired
10001 22 32 42 before trigger fired
@ -87,6 +106,19 @@ stuff after trigger fired
stuff after trigger fired
stuff after trigger fired
stuff after trigger fired
COPY x (b, e) TO stdout WITH NULL 'I''m null';
21 before trigger fired
22 before trigger fired
23 before trigger fired
24 before trigger fired
25 before trigger fired
26 before trigger fired
I'm null before trigger fired
1 after trigger fired
2 after trigger fired
3 after trigger fired
4 after trigger fired
5 after trigger fired
DROP TABLE x;
DROP FUNCTION fn_x_before();
DROP FUNCTION fn_x_after();

View File

@ -571,3 +571,163 @@ select * from def_view_test;
drop rule def_view_test_ins on def_view_test;
drop view def_view_test;
drop table def_test;
-- alter table / drop column tests
-- try altering system catalogs, should fail
alter table pg_class drop column relname;
-- try altering non-existent table, should fail
alter table foo drop column bar;
-- test dropping columns
create table atacc1 (a int4 not null, b int4, c int4 not null, d int4);
insert into atacc1 values (1, 2, 3, 4);
alter table atacc1 drop a;
alter table atacc1 drop a;
-- SELECTs
select * from atacc1;
select * from atacc1 order by a;
select * from atacc1 order by "........pg.dropped.1........";
select * from atacc1 group by a;
select * from atacc1 group by "........pg.dropped.1........";
select atacc1.* from atacc1;
select a from atacc1;
select atacc1.a from atacc1;
select b,c,d from atacc1;
select a,b,c,d from atacc1;
select * from atacc1 where a = 1;
select "........pg.dropped.1........" from atacc1;
select atacc1."........pg.dropped.1........" from atacc1;
select "........pg.dropped.1........",b,c,d from atacc1;
select * from atacc1 where "........pg.dropped.1........" = 1;
-- UPDATEs
update atacc1 set a = 3;
update atacc1 set b = 2 where a = 3;
update atacc1 set "........pg.dropped.1........" = 3;
update atacc1 set b = 2 where "........pg.dropped.1........" = 3;
-- INSERTs
insert into atacc1 values (10, 11, 12, 13);
insert into atacc1 values (default, 11, 12, 13);
insert into atacc1 values (11, 12, 13);
insert into atacc1 (a) values (10);
insert into atacc1 (a) values (default);
insert into atacc1 (a,b,c,d) values (10,11,12,13);
insert into atacc1 (a,b,c,d) values (default,11,12,13);
insert into atacc1 (b,c,d) values (11,12,13);
insert into atacc1 ("........pg.dropped.1........") values (10);
insert into atacc1 ("........pg.dropped.1........") values (default);
insert into atacc1 ("........pg.dropped.1........",b,c,d) values (10,11,12,13);
insert into atacc1 ("........pg.dropped.1........",b,c,d) values (default,11,12,13);
-- DELETEs
delete from atacc1 where a = 3;
delete from atacc1 where "........pg.dropped.1........" = 3;
delete from atacc1;
-- try dropping a non-existent column, should fail
alter table atacc1 drop bar;
-- try dropping the oid column, should fail
alter table atacc1 drop oid;
-- try creating a view and altering that, should fail
create view myview as select * from atacc1;
select * from myview;
alter table myview drop d;
drop view myview;
-- test some commands to make sure they fail on the dropped column
analyze atacc1(a);
analyze atacc1("........pg.dropped.1........");
vacuum analyze atacc1(a);
vacuum analyze atacc1("........pg.dropped.1........");
comment on column atacc1.a is 'testing';
comment on column atacc1."........pg.dropped.1........" is 'testing';
alter table atacc1 alter a set storage plain;
alter table atacc1 alter "........pg.dropped.1........" set storage plain;
alter table atacc1 alter a set statistics 0;
alter table atacc1 alter "........pg.dropped.1........" set statistics 0;
alter table atacc1 alter a set default 3;
alter table atacc1 alter "........pg.dropped.1........" set default 3;
alter table atacc1 alter a drop default;
alter table atacc1 alter "........pg.dropped.1........" drop default;
alter table atacc1 alter a set not null;
alter table atacc1 alter "........pg.dropped.1........" set not null;
alter table atacc1 alter a drop not null;
alter table atacc1 alter "........pg.dropped.1........" drop not null;
alter table atacc1 rename a to x;
alter table atacc1 rename "........pg.dropped.1........" to x;
alter table atacc1 add primary key(a);
alter table atacc1 add primary key("........pg.dropped.1........");
alter table atacc1 add unique(a);
alter table atacc1 add unique("........pg.dropped.1........");
alter table atacc1 add check (a > 3);
alter table atacc1 add check ("........pg.dropped.1........" > 3);
create table atacc2 (id int4 unique);
alter table atacc1 add foreign key (a) references atacc2(id);
alter table atacc1 add foreign key ("........pg.dropped.1........") references atacc2(id);
alter table atacc2 add foreign key (id) references atacc1(a);
alter table atacc2 add foreign key (id) references atacc1("........pg.dropped.1........");
drop table atacc2;
create index "testing_idx" on atacc1(a);
create index "testing_idx" on atacc1("........pg.dropped.1........");
-- test create as and select into
insert into atacc1 values (21, 22, 23);
create table test1 as select * from atacc1;
select * from test1;
drop table test1;
select * into test2 from atacc1;
select * from test2;
drop table test2;
-- try dropping all columns
alter table atacc1 drop c;
alter table atacc1 drop d;
alter table atacc1 drop b;
select * from atacc1;
drop table atacc1;
-- test inheritance
create table parent (a int, b int, c int);
insert into parent values (1, 2, 3);
alter table parent drop a;
create table child (d varchar(255)) inherits (parent);
insert into child values (12, 13, 'testing');
select * from parent;
select * from child;
alter table parent drop c;
select * from parent;
select * from child;
drop table child;
drop table parent;
-- test copy in/out
create table test (a int4, b int4, c int4);
insert into test values (1,2,3);
alter table test drop a;
copy test to stdout;
copy test(a) to stdout;
copy test("........pg.dropped.1........") to stdout;
copy test from stdin;
10 11 12
\.
select * from test;
copy test from stdin;
21 22
\.
select * from test;
copy test(a) from stdin;
copy test("........pg.dropped.1........") from stdin;
copy test(b,c) from stdin;
31 32
\.
select * from test;
drop table test;

View File

@ -76,6 +76,9 @@ COPY x (b, c, d, e) from stdin with oids delimiter ',' null 'x';
500000,x,45,80,90
\.
-- check results of copy in
SELECT * FROM x;
-- COPY w/ oids on a table w/o oids should fail
CREATE TABLE no_oids (
a int,
@ -89,8 +92,11 @@ INSERT INTO no_oids (a, b) VALUES (20, 30);
COPY no_oids FROM stdin WITH OIDS;
COPY no_oids TO stdout WITH OIDS;
-- check copy out
COPY x TO stdout;
COPY x (c, e) TO stdout;
COPY x (b, e) TO stdout WITH NULL 'I''m null';
DROP TABLE x;
DROP FUNCTION fn_x_before();
DROP FUNCTION fn_x_after();