@@ -328,8 +328,9 @@ static void ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recu
328328 bool is_view , AlterTableCmd * cmd , LOCKMODE lockmode );
329329static ObjectAddress ATExecAddColumn (List * * wqueue , AlteredTableInfo * tab ,
330330 Relation rel , ColumnDef * colDef , bool isOid ,
331- bool recurse , bool recursing , LOCKMODE lockmode );
332- static void check_for_column_name_collision (Relation rel , const char * colname );
331+ bool recurse , bool recursing , bool if_not_exists , LOCKMODE lockmode );
332+ static bool check_for_column_name_collision (Relation rel , const char * colname ,
333+ bool if_not_exists );
333334static void add_column_datatype_dependency (Oid relid , int32 attnum , Oid typid );
334335static void add_column_collation_dependency (Oid relid , int32 attnum , Oid collid );
335336static void ATPrepAddOids (List * * wqueue , Relation rel , bool recurse ,
@@ -2304,7 +2305,7 @@ renameatt_internal(Oid myrelid,
23042305 oldattname )));
23052306
23062307 /* new name should not already exist */
2307- check_for_column_name_collision (targetrelation , newattname );
2308+ ( void ) check_for_column_name_collision (targetrelation , newattname , false );
23082309
23092310 /* apply the update */
23102311 namestrcpy (& (attform -> attname ), newattname );
@@ -3455,11 +3456,11 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
34553456 case AT_AddColumnToView : /* add column via CREATE OR REPLACE
34563457 * VIEW */
34573458 address = ATExecAddColumn (wqueue , tab , rel , (ColumnDef * ) cmd -> def ,
3458- false, false, false, lockmode );
3459+ false, false, false, false, lockmode );
34593460 break ;
34603461 case AT_AddColumnRecurse :
34613462 address = ATExecAddColumn (wqueue , tab , rel , (ColumnDef * ) cmd -> def ,
3462- false, true, false, lockmode );
3463+ false, true, false, cmd -> missing_ok , lockmode );
34633464 break ;
34643465 case AT_ColumnDefault : /* ALTER COLUMN DEFAULT */
34653466 address = ATExecColumnDefault (rel , cmd -> name , cmd -> def , lockmode );
@@ -3572,14 +3573,14 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
35723573 if (cmd -> def != NULL )
35733574 address =
35743575 ATExecAddColumn (wqueue , tab , rel , (ColumnDef * ) cmd -> def ,
3575- true, false, false, lockmode );
3576+ true, false, false, cmd -> missing_ok , lockmode );
35763577 break ;
35773578 case AT_AddOidsRecurse : /* SET WITH OIDS */
35783579 /* Use the ADD COLUMN code, unless prep decided to do nothing */
35793580 if (cmd -> def != NULL )
35803581 address =
35813582 ATExecAddColumn (wqueue , tab , rel , (ColumnDef * ) cmd -> def ,
3582- true, true, false, lockmode );
3583+ true, true, false, cmd -> missing_ok , lockmode );
35833584 break ;
35843585 case AT_DropOids : /* SET WITHOUT OIDS */
35853586
@@ -4677,7 +4678,7 @@ ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
46774678static ObjectAddress
46784679ATExecAddColumn (List * * wqueue , AlteredTableInfo * tab , Relation rel ,
46794680 ColumnDef * colDef , bool isOid ,
4680- bool recurse , bool recursing , LOCKMODE lockmode )
4681+ bool recurse , bool recursing , bool if_not_exists , LOCKMODE lockmode )
46814682{
46824683 Oid myrelid = RelationGetRelid (rel );
46834684 Relation pgclass ,
@@ -4771,8 +4772,14 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
47714772 elog (ERROR , "cache lookup failed for relation %u" , myrelid );
47724773 relkind = ((Form_pg_class ) GETSTRUCT (reltup ))-> relkind ;
47734774
4774- /* new name should not already exist */
4775- check_for_column_name_collision (rel , colDef -> colname );
4775+ /* skip if the name already exists and if_not_exists is true */
4776+ if (!check_for_column_name_collision (rel , colDef -> colname , if_not_exists ))
4777+ {
4778+ heap_close (attrdesc , RowExclusiveLock );
4779+ heap_freetuple (reltup );
4780+ heap_close (pgclass , RowExclusiveLock );
4781+ return InvalidObjectAddress ;
4782+ }
47764783
47774784 /* Determine the new attribute's number */
47784785 if (isOid )
@@ -5002,7 +5009,8 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
50025009
50035010 /* Recurse to child; return value is ignored */
50045011 ATExecAddColumn (wqueue , childtab , childrel ,
5005- colDef , isOid , recurse , true, lockmode );
5012+ colDef , isOid , recurse , true,
5013+ if_not_exists , lockmode );
50065014
50075015 heap_close (childrel , NoLock );
50085016 }
@@ -5013,10 +5021,11 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
50135021
50145022/*
50155023 * If a new or renamed column will collide with the name of an existing
5016- * column, error out.
5024+ * column and if_not_exists is false then error out, else do nothing .
50175025 */
5018- static void
5019- check_for_column_name_collision (Relation rel , const char * colname )
5026+ static bool
5027+ check_for_column_name_collision (Relation rel , const char * colname ,
5028+ bool if_not_exists )
50205029{
50215030 HeapTuple attTuple ;
50225031 int attnum ;
@@ -5029,7 +5038,7 @@ check_for_column_name_collision(Relation rel, const char *colname)
50295038 ObjectIdGetDatum (RelationGetRelid (rel )),
50305039 PointerGetDatum (colname ));
50315040 if (!HeapTupleIsValid (attTuple ))
5032- return ;
5041+ return true ;
50335042
50345043 attnum = ((Form_pg_attribute ) GETSTRUCT (attTuple ))-> attnum ;
50355044 ReleaseSysCache (attTuple );
@@ -5045,10 +5054,23 @@ check_for_column_name_collision(Relation rel, const char *colname)
50455054 errmsg ("column name \"%s\" conflicts with a system column name" ,
50465055 colname )));
50475056 else
5057+ {
5058+ if (if_not_exists )
5059+ {
5060+ ereport (NOTICE ,
5061+ (errcode (ERRCODE_DUPLICATE_COLUMN ),
5062+ errmsg ("column \"%s\" of relation \"%s\" already exists, skipping" ,
5063+ colname , RelationGetRelationName (rel ))));
5064+ return false;
5065+ }
5066+
50485067 ereport (ERROR ,
50495068 (errcode (ERRCODE_DUPLICATE_COLUMN ),
50505069 errmsg ("column \"%s\" of relation \"%s\" already exists" ,
50515070 colname , RelationGetRelationName (rel ))));
5071+ }
5072+
5073+ return true;
50525074}
50535075
50545076/*
0 commit comments