diff --git a/src/gausskernel/optimizer/commands/tablecmds.cpp b/src/gausskernel/optimizer/commands/tablecmds.cpp index 241966692ec46ab23d2037dfd37c26057494b7ef..81a5af61cafc66af1f4f31f635f8ace492f93048 100644 --- a/src/gausskernel/optimizer/commands/tablecmds.cpp +++ b/src/gausskernel/optimizer/commands/tablecmds.cpp @@ -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 * diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 4be0a3033a098fe89540c71f4f8b6c8dc038c1a7..31dd4600de971b85ca717a40dbc83d3cf3c5b624 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -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; diff --git a/src/test/regress/input/cstore_alter_table3.source b/src/test/regress/input/cstore_alter_table3.source index 11b93abc1c8a6aaf2ed812d4fe64748e8f48d7ad..fff613812f1026bacda63977e4413cd1137051fb 100644 --- a/src/test/regress/input/cstore_alter_table3.source +++ b/src/test/regress/input/cstore_alter_table3.source @@ -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); diff --git a/src/test/regress/output/cstore_alter_table3.source b/src/test/regress/output/cstore_alter_table3.source index 6251e72b454512e20c5410c60dc4027ec0a056e2..266f7dde1ebe8f164cf1785136bb08fdec1aa026 100644 --- a/src/test/regress/output/cstore_alter_table3.source +++ b/src/test/regress/output/cstore_alter_table3.source @@ -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)); diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index 0a8a9714754be60a24cdf57f650a51ee0a8fa565..d98b366d3ff47a1d432983ccf98a1a5e618e72d6 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -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);