@@ -297,11 +297,11 @@ static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
297
297
IndexStmt * stmt , bool is_rebuild );
298
298
static void ATExecAddConstraint (List * * wqueue ,
299
299
AlteredTableInfo * tab , Relation rel ,
300
- Constraint * newConstraint , bool recurse );
300
+ Constraint * newConstraint , bool recurse , bool is_readd );
301
301
static void ATAddCheckConstraint (List * * wqueue ,
302
302
AlteredTableInfo * tab , Relation rel ,
303
303
Constraint * constr ,
304
- bool recurse , bool recursing );
304
+ bool recurse , bool recursing , bool is_readd );
305
305
static void ATAddForeignKeyConstraint (AlteredTableInfo * tab , Relation rel ,
306
306
Constraint * fkconstraint );
307
307
static void ATExecDropConstraint (Relation rel , const char * constrName ,
@@ -2663,11 +2663,15 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
2663
2663
break ;
2664
2664
case AT_AddConstraint : /* ADD CONSTRAINT */
2665
2665
ATExecAddConstraint (wqueue , tab , rel , (Constraint * ) cmd -> def ,
2666
- false);
2666
+ false, false );
2667
2667
break ;
2668
2668
case AT_AddConstraintRecurse : /* ADD CONSTRAINT with recursion */
2669
2669
ATExecAddConstraint (wqueue , tab , rel , (Constraint * ) cmd -> def ,
2670
- true);
2670
+ true, false);
2671
+ break ;
2672
+ case AT_ReAddConstraint : /* Re-add pre-existing check constraint */
2673
+ ATExecAddConstraint (wqueue , tab , rel , (Constraint * ) cmd -> def ,
2674
+ false, true);
2671
2675
break ;
2672
2676
case AT_DropConstraint : /* DROP CONSTRAINT */
2673
2677
ATExecDropConstraint (rel , cmd -> name , cmd -> behavior ,
@@ -4516,7 +4520,7 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
4516
4520
*/
4517
4521
static void
4518
4522
ATExecAddConstraint (List * * wqueue , AlteredTableInfo * tab , Relation rel ,
4519
- Constraint * newConstraint , bool recurse )
4523
+ Constraint * newConstraint , bool recurse , bool is_readd )
4520
4524
{
4521
4525
Assert (IsA (newConstraint , Constraint ));
4522
4526
@@ -4529,7 +4533,7 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
4529
4533
{
4530
4534
case CONSTR_CHECK :
4531
4535
ATAddCheckConstraint (wqueue , tab , rel ,
4532
- newConstraint , recurse , false);
4536
+ newConstraint , recurse , false, is_readd );
4533
4537
break ;
4534
4538
4535
4539
case CONSTR_FOREIGN :
@@ -4581,10 +4585,18 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
4581
4585
* AddRelationNewConstraints would normally assign different names to the
4582
4586
* child constraints. To fix that, we must capture the name assigned at
4583
4587
* the parent table and pass that down.
4588
+ *
4589
+ * When re-adding a previously existing constraint (during ALTER COLUMN TYPE),
4590
+ * we don't need to recurse here, because recursion will be carried out at a
4591
+ * higher level; the constraint name issue doesn't apply because the names
4592
+ * have already been assigned and are just being re-used. We need a separate
4593
+ * "is_readd" flag for that; just setting recurse=false would result in an
4594
+ * error if there are child tables.
4584
4595
*/
4585
4596
static void
4586
4597
ATAddCheckConstraint (List * * wqueue , AlteredTableInfo * tab , Relation rel ,
4587
- Constraint * constr , bool recurse , bool recursing )
4598
+ Constraint * constr , bool recurse , bool recursing ,
4599
+ bool is_readd )
4588
4600
{
4589
4601
List * newcons ;
4590
4602
ListCell * lcon ;
@@ -4643,6 +4655,13 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
4643
4655
if (newcons == NIL )
4644
4656
return ;
4645
4657
4658
+ /*
4659
+ * Also, in a re-add operation, we don't need to recurse (that will be
4660
+ * handled at higher levels).
4661
+ */
4662
+ if (is_readd )
4663
+ return ;
4664
+
4646
4665
/*
4647
4666
* Propagate to children as appropriate. Unlike most other ALTER
4648
4667
* routines, we have to do this one level of recursion at a time; we can't
@@ -4675,7 +4694,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
4675
4694
4676
4695
/* Recurse to child */
4677
4696
ATAddCheckConstraint (wqueue , childtab , childrel ,
4678
- constr , recurse , true);
4697
+ constr , recurse , true, is_readd );
4679
4698
4680
4699
heap_close (childrel , NoLock );
4681
4700
}
@@ -6330,6 +6349,10 @@ ATPostAlterTypeParse(char *cmd, List **wqueue)
6330
6349
/*
6331
6350
* Attach each generated command to the proper place in the work queue.
6332
6351
* Note this could result in creation of entirely new work-queue entries.
6352
+ *
6353
+ * Also note that we have to tweak the command subtypes, because it turns
6354
+ * out that re-creation of indexes and constraints has to act a bit
6355
+ * differently from initial creation.
6333
6356
*/
6334
6357
foreach (list_item , querytree_list )
6335
6358
{
@@ -6373,6 +6396,7 @@ ATPostAlterTypeParse(char *cmd, List **wqueue)
6373
6396
lappend (tab -> subcmds [AT_PASS_OLD_INDEX ], cmd );
6374
6397
break ;
6375
6398
case AT_AddConstraint :
6399
+ cmd -> subtype = AT_ReAddConstraint ;
6376
6400
tab -> subcmds [AT_PASS_OLD_CONSTR ] =
6377
6401
lappend (tab -> subcmds [AT_PASS_OLD_CONSTR ], cmd );
6378
6402
break ;
0 commit comments