@@ -328,9 +328,10 @@ static void ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recu
328
328
bool is_view , AlterTableCmd * cmd , LOCKMODE lockmode );
329
329
static ObjectAddress ATExecAddColumn (List * * wqueue , AlteredTableInfo * tab ,
330
330
Relation rel , ColumnDef * colDef , bool isOid ,
331
- bool recurse , bool recursing , bool if_not_exists , LOCKMODE lockmode );
331
+ bool recurse , bool recursing ,
332
+ bool if_not_exists , LOCKMODE lockmode );
332
333
static bool check_for_column_name_collision (Relation rel , const char * colname ,
333
- bool if_not_exists );
334
+ bool if_not_exists );
334
335
static void add_column_datatype_dependency (Oid relid , int32 attnum , Oid typid );
335
336
static void add_column_collation_dependency (Oid relid , int32 attnum , Oid collid );
336
337
static void ATPrepAddOids (List * * wqueue , Relation rel , bool recurse ,
@@ -3457,11 +3458,13 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
3457
3458
case AT_AddColumnToView : /* add column via CREATE OR REPLACE
3458
3459
* VIEW */
3459
3460
address = ATExecAddColumn (wqueue , tab , rel , (ColumnDef * ) cmd -> def ,
3460
- false, false, false, false, lockmode );
3461
+ false, false, false,
3462
+ false, lockmode );
3461
3463
break ;
3462
3464
case AT_AddColumnRecurse :
3463
3465
address = ATExecAddColumn (wqueue , tab , rel , (ColumnDef * ) cmd -> def ,
3464
- false, true, false, cmd -> missing_ok , lockmode );
3466
+ false, true, false,
3467
+ cmd -> missing_ok , lockmode );
3465
3468
break ;
3466
3469
case AT_ColumnDefault : /* ALTER COLUMN DEFAULT */
3467
3470
address = ATExecColumnDefault (rel , cmd -> name , cmd -> def , lockmode );
@@ -3516,7 +3519,7 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
3516
3519
* constraint */
3517
3520
address =
3518
3521
ATExecAddConstraint (wqueue , tab , rel , (Constraint * ) cmd -> def ,
3519
- false , true, lockmode );
3522
+ true , true, lockmode );
3520
3523
break ;
3521
3524
case AT_ReAddComment : /* Re-add existing comment */
3522
3525
address = CommentObject ((CommentStmt * ) cmd -> def );
@@ -3574,14 +3577,16 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
3574
3577
if (cmd -> def != NULL )
3575
3578
address =
3576
3579
ATExecAddColumn (wqueue , tab , rel , (ColumnDef * ) cmd -> def ,
3577
- true, false, false, cmd -> missing_ok , lockmode );
3580
+ true, false, false,
3581
+ cmd -> missing_ok , lockmode );
3578
3582
break ;
3579
3583
case AT_AddOidsRecurse : /* SET WITH OIDS */
3580
3584
/* Use the ADD COLUMN code, unless prep decided to do nothing */
3581
3585
if (cmd -> def != NULL )
3582
3586
address =
3583
3587
ATExecAddColumn (wqueue , tab , rel , (ColumnDef * ) cmd -> def ,
3584
- true, true, false, cmd -> missing_ok , lockmode );
3588
+ true, true, false,
3589
+ cmd -> missing_ok , lockmode );
3585
3590
break ;
3586
3591
case AT_DropOids : /* SET WITHOUT OIDS */
3587
3592
@@ -4691,7 +4696,8 @@ ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
4691
4696
static ObjectAddress
4692
4697
ATExecAddColumn (List * * wqueue , AlteredTableInfo * tab , Relation rel ,
4693
4698
ColumnDef * colDef , bool isOid ,
4694
- bool recurse , bool recursing , bool if_not_exists , LOCKMODE lockmode )
4699
+ bool recurse , bool recursing ,
4700
+ bool if_not_exists , LOCKMODE lockmode )
4695
4701
{
4696
4702
Oid myrelid = RelationGetRelid (rel );
4697
4703
Relation pgclass ,
@@ -6090,13 +6096,6 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
6090
6096
* AddRelationNewConstraints would normally assign different names to the
6091
6097
* child constraints. To fix that, we must capture the name assigned at
6092
6098
* the parent table and pass that down.
6093
- *
6094
- * When re-adding a previously existing constraint (during ALTER COLUMN TYPE),
6095
- * we don't need to recurse here, because recursion will be carried out at a
6096
- * higher level; the constraint name issue doesn't apply because the names
6097
- * have already been assigned and are just being re-used. We need a separate
6098
- * "is_readd" flag for that; just setting recurse=false would result in an
6099
- * error if there are child tables.
6100
6099
*/
6101
6100
static ObjectAddress
6102
6101
ATAddCheckConstraint (List * * wqueue , AlteredTableInfo * tab , Relation rel ,
@@ -6125,7 +6124,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
6125
6124
*/
6126
6125
newcons = AddRelationNewConstraints (rel , NIL ,
6127
6126
list_make1 (copyObject (constr )),
6128
- recursing , /* allow_merge */
6127
+ recursing | is_readd , /* allow_merge */
6129
6128
!recursing , /* is_local */
6130
6129
is_readd ); /* is_internal */
6131
6130
@@ -6174,10 +6173,8 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
6174
6173
6175
6174
/*
6176
6175
* If adding a NO INHERIT constraint, no need to find our children.
6177
- * Likewise, in a re-add operation, we don't need to recurse (that will be
6178
- * handled at higher levels).
6179
6176
*/
6180
- if (constr -> is_no_inherit || is_readd )
6177
+ if (constr -> is_no_inherit )
6181
6178
return address ;
6182
6179
6183
6180
/*
@@ -8209,7 +8206,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
8209
8206
if (!list_member_oid (tab -> changedConstraintOids ,
8210
8207
foundObject .objectId ))
8211
8208
{
8212
- char * defstring = pg_get_constraintdef_string (foundObject .objectId );
8209
+ char * defstring = pg_get_constraintdef_command (foundObject .objectId );
8213
8210
8214
8211
/*
8215
8212
* Put NORMAL dependencies at the front of the list and
@@ -8584,10 +8581,30 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
8584
8581
def_item , tab -> changedConstraintDefs )
8585
8582
{
8586
8583
Oid oldId = lfirst_oid (oid_item );
8584
+ HeapTuple tup ;
8585
+ Form_pg_constraint con ;
8587
8586
Oid relid ;
8588
8587
Oid confrelid ;
8588
+ bool conislocal ;
8589
+
8590
+ tup = SearchSysCache1 (CONSTROID , ObjectIdGetDatum (oldId ));
8591
+ if (!HeapTupleIsValid (tup )) /* should not happen */
8592
+ elog (ERROR , "cache lookup failed for constraint %u" , oldId );
8593
+ con = (Form_pg_constraint ) GETSTRUCT (tup );
8594
+ relid = con -> conrelid ;
8595
+ confrelid = con -> confrelid ;
8596
+ conislocal = con -> conislocal ;
8597
+ ReleaseSysCache (tup );
8598
+
8599
+ /*
8600
+ * If the constraint is inherited (only), we don't want to inject a
8601
+ * new definition here; it'll get recreated when ATAddCheckConstraint
8602
+ * recurses from adding the parent table's constraint. But we had to
8603
+ * carry the info this far so that we can drop the constraint below.
8604
+ */
8605
+ if (!conislocal )
8606
+ continue ;
8589
8607
8590
- get_constraint_relation_oids (oldId , & relid , & confrelid );
8591
8608
ATPostAlterTypeParse (oldId , relid , confrelid ,
8592
8609
(char * ) lfirst (def_item ),
8593
8610
wqueue , lockmode , tab -> rewrite );
@@ -8761,7 +8778,7 @@ ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd,
8761
8778
rel , con -> conname );
8762
8779
}
8763
8780
else
8764
- elog (ERROR , "unexpected statement type : %d" ,
8781
+ elog (ERROR , "unexpected statement subtype : %d" ,
8765
8782
(int ) cmd -> subtype );
8766
8783
}
8767
8784
}
@@ -11272,19 +11289,19 @@ ATPrepChangePersistence(Relation rel, bool toLogged)
11272
11289
if (foreignrel -> rd_rel -> relpersistence != RELPERSISTENCE_PERMANENT )
11273
11290
ereport (ERROR ,
11274
11291
(errcode (ERRCODE_INVALID_TABLE_DEFINITION ),
11275
- errmsg ("could not change table \"%s\" to logged because it references unlogged table \"%s\"" ,
11276
- RelationGetRelationName (rel ),
11277
- RelationGetRelationName (foreignrel )),
11292
+ errmsg ("could not change table \"%s\" to logged because it references unlogged table \"%s\"" ,
11293
+ RelationGetRelationName (rel ),
11294
+ RelationGetRelationName (foreignrel )),
11278
11295
errtableconstraint (rel , NameStr (con -> conname ))));
11279
11296
}
11280
11297
else
11281
11298
{
11282
11299
if (foreignrel -> rd_rel -> relpersistence == RELPERSISTENCE_PERMANENT )
11283
11300
ereport (ERROR ,
11284
11301
(errcode (ERRCODE_INVALID_TABLE_DEFINITION ),
11285
- errmsg ("could not change table \"%s\" to unlogged because it references logged table \"%s\"" ,
11286
- RelationGetRelationName (rel ),
11287
- RelationGetRelationName (foreignrel )),
11302
+ errmsg ("could not change table \"%s\" to unlogged because it references logged table \"%s\"" ,
11303
+ RelationGetRelationName (rel ),
11304
+ RelationGetRelationName (foreignrel )),
11288
11305
errtableconstraint (rel , NameStr (con -> conname ))));
11289
11306
}
11290
11307
0 commit comments