alter table modify not allow duplicate column name

This commit is contained in:
chenxiaobin 2020-08-06 17:14:56 +08:00
parent e2f884c4ba
commit 02dca5dfc4
5 changed files with 43 additions and 0 deletions

View File

@ -610,6 +610,8 @@ static void ResetRelRedisCtidRelOptions(
static bool WLMRelationCanTruncate(Relation rel);
static void alter_partition_policy_if_needed(Relation rel, List* defList);
static OnCommitAction GttOncommitOption(const List *options);
static void ATCheckDuplicateColumn(AlterTableCmd* cmd, List* tabCmds);
static void ATCheckNotNullConstr(AlterTableCmd* cmd, AlteredTableInfo* tab);
/* get all partitions oid */
@ -5923,12 +5925,14 @@ static void ATPrepCmd(List** wqueue, Relation rel, AlterTableCmd* cmd, bool recu
ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
/* No command-specific prep needed */
pass = AT_PASS_DROP;
ATCheckNotNullConstr(cmd, tab);
break;
case AT_SetNotNull: /* ALTER COLUMN SET NOT NULL */
ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE);
ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
/* No command-specific prep needed */
pass = AT_PASS_ADD_CONSTR;
ATCheckNotNullConstr(cmd, tab);
break;
case AT_SetStatistics: /* ALTER COLUMN SET STATISTICS */
ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode);
@ -6020,6 +6024,7 @@ static void ATPrepCmd(List** wqueue, Relation rel, AlterTableCmd* cmd, bool recu
/* Performs own recursion */
ATPrepAlterColumnType(wqueue, tab, rel, recurse, recursing, cmd, lockmode);
pass = AT_PASS_ALTER_TYPE;
ATCheckDuplicateColumn(cmd, tab->subcmds[pass]);
break;
case AT_AlterColumnGenericOptions:
ATSimplePermissions(rel, ATT_FOREIGN_TABLE);
@ -6206,6 +6211,31 @@ static void ATPrepCmd(List** wqueue, Relation rel, AlterTableCmd* cmd, bool recu
tab->subcmds[pass] = lappend(tab->subcmds[pass], cmd);
}
/*
* ATCheckDuplicateColumn: Check AT if exists duplicate column name
*/
static void ATCheckDuplicateColumn(AlterTableCmd* cmd, List* tabCmds)
{
ListCell* tcmd = NULL;
foreach (tcmd, tabCmds) {
AlterTableCmd* acmd = (AlterTableCmd*)lfirst(tcmd);
if (strcmp(acmd->name, cmd->name) == 0) {
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot alter type of column \"%s\" twice", cmd->name)));
}
}
}
/*
* ATCheckNotNullConstr: Check AT set/drop not null if exists duplicate column name
*/
static void ATCheckNotNullConstr(AlterTableCmd* cmd, AlteredTableInfo* tab)
{
ATCheckDuplicateColumn(cmd, tab->subcmds[AT_PASS_ADD_CONSTR]);
ATCheckDuplicateColumn(cmd, tab->subcmds[AT_PASS_DROP]);
}
/*
* ATRewriteCatalogs
*

View File

@ -865,6 +865,8 @@ ERROR: null value in column "b" violates not-null constraint
DETAIL: Failing row contains (1, null).
alter table test_modify modify (b constraint ak null);
insert into test_modify values(1,null);
alter table test_modify modify (a null, a not null);
ERROR: cannot alter type of column "a" twice
-- try alter view should fail
create view test_modify_view as select * from test_modify;
alter table test_modify_view modify (a not null enable);
@ -2660,6 +2662,8 @@ ALTER TABLE MODIFY_TABLE_A MODIFY (myint1 VARCHAR(13), mychar1 INT);
b | character(1) |
mychar4 | character(1) |
ALTER TABLE MODIFY_TABLE_A MODIFY (myint1 VARCHAR(13), myint1 INT);
ERROR: cannot alter type of column "myint1" twice
DROP TABLE MODIFY_TABLE_A;
create table test_alter_type(a int,b text);
alter table test_alter_type alter column a type regclass;

View File

@ -144,6 +144,9 @@ SELECT DISTINCT * FROM alter_addcols_64;
CREATE TABLE alter_addcols_79(a int, b int) WITH ( ORIENTATION = COLUMN);
ALTER TABLE alter_addcols_79 ALTER COLUMN b SET DATA TYPE varchar(40) USING 'ldiloveyouhelloworldiloveyouhelloworl', ALTER COLUMN b SET DATA TYPE bigint;
ALTER TABLE alter_addcols_79 ALTER COLUMN b SET DATA TYPE varchar(40) USING 'ldiloveyouhelloworldiloveyouhelloworl', ALTER COLUMN b SET DATA TYPE varchar(40) USING 'ldiloveyouhelloworldiloveyouhelloworl';
CREATE TABLE alter_cons (a int, b int) WITH (ORIENTATION = ROW);
ALTER TABLE alter_cons ALTER a DROP NOT NULL, ALTER a SET NOT NULL;
DROP TABLE alter_cons;
-- test multiple SET DATA TYPE within one sql clause.
CREATE TABLE alter_addcols_80(a int, b int, c varchar(10)) WITH ( ORIENTATION = COLUMN);

View File

@ -283,6 +283,10 @@ ALTER TABLE alter_addcols_79 ALTER COLUMN b SET DATA TYPE varchar(40) USING 'ldi
ERROR: cannot alter type of column "b" twice
ALTER TABLE alter_addcols_79 ALTER COLUMN b SET DATA TYPE varchar(40) USING 'ldiloveyouhelloworldiloveyouhelloworl', ALTER COLUMN b SET DATA TYPE varchar(40) USING 'ldiloveyouhelloworldiloveyouhelloworl';
ERROR: cannot alter type of column "b" twice
CREATE TABLE alter_cons (a int, b int) WITH (ORIENTATION = ROW);
ALTER TABLE alter_cons ALTER a DROP NOT NULL, ALTER a SET NOT NULL;
ERROR: cannot alter type of column "a" twice
DROP TABLE alter_cons;
-- test multiple SET DATA TYPE within one sql clause.
CREATE TABLE alter_addcols_80(a int, b int, c varchar(10)) WITH ( ORIENTATION = COLUMN);
create table base_alter_addcols(a int, b int, c varchar(10));

View File

@ -693,6 +693,7 @@ insert into test_modify values(1,1);
insert into test_modify values(1,null);
alter table test_modify modify (b constraint ak null);
insert into test_modify values(1,null);
alter table test_modify modify (a null, a not null);
-- try alter view should fail
create view test_modify_view as select * from test_modify;
alter table test_modify_view modify (a not null enable);
@ -1769,6 +1770,7 @@ ALTER TABLE MODIFY_TABLE_A MODIFY (myint1 VARCHAR(12));
\d MODIFY_TABLE_A
ALTER TABLE MODIFY_TABLE_A MODIFY (myint1 VARCHAR(13), mychar1 INT);
\d MODIFY_TABLE_A
ALTER TABLE MODIFY_TABLE_A MODIFY (myint1 VARCHAR(13), myint1 INT);
DROP TABLE MODIFY_TABLE_A;
create table test_alter_type(a int,b text);