alter-type-readd-constraint.patch
application/octet-stream
Filename: alter-type-readd-constraint.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/commands/tablecmds.c | 34 | 15 |
| src/include/nodes/parsenodes.h | 1 | 0 |
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 359d478..50c93fe 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -335,13 +335,15 @@ static void ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
IndexStmt *stmt, bool is_rebuild, LOCKMODE lockmode);
static void ATExecAddConstraint(List **wqueue,
AlteredTableInfo *tab, Relation rel,
- Constraint *newConstraint, bool recurse, LOCKMODE lockmode);
+ Constraint *newConstraint, bool recurse, bool check_no_children,
+ LOCKMODE lockmode);
static void ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel,
IndexStmt *stmt, LOCKMODE lockmode);
static void ATAddCheckConstraint(List **wqueue,
AlteredTableInfo *tab, Relation rel,
Constraint *constr,
- bool recurse, bool recursing, LOCKMODE lockmode);
+ bool recurse, bool recursing, bool check_no_children,
+ LOCKMODE lockmode);
static void ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
Constraint *fkconstraint, LOCKMODE lockmode);
static void ATExecDropConstraint(Relation rel, const char *constrName,
@@ -3248,11 +3250,15 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
break;
case AT_AddConstraint: /* ADD CONSTRAINT */
ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def,
- false, lockmode);
+ false, true, lockmode);
+ break;
+ case AT_ReAddConstraint: /* Re-add previously dropped CONSTRAINT */
+ ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def,
+ false, false, lockmode);
break;
case AT_AddConstraintRecurse: /* ADD CONSTRAINT with recursion */
ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def,
- true, lockmode);
+ true, true, lockmode);
break;
case AT_AddIndexConstraint: /* ADD CONSTRAINT USING INDEX */
ATExecAddIndexConstraint(tab, rel, (IndexStmt *) cmd->def, lockmode);
@@ -5499,7 +5505,8 @@ ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel,
*/
static void
ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
- Constraint *newConstraint, bool recurse, LOCKMODE lockmode)
+ Constraint *newConstraint, bool recurse, bool check_no_children,
+ LOCKMODE lockmode)
{
Assert(IsA(newConstraint, Constraint));
@@ -5512,7 +5519,8 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
{
case CONSTR_CHECK:
ATAddCheckConstraint(wqueue, tab, rel,
- newConstraint, recurse, false, lockmode);
+ newConstraint, recurse, false, check_no_children,
+ lockmode);
break;
case CONSTR_FOREIGN:
@@ -5568,7 +5576,7 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
static void
ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
Constraint *constr, bool recurse, bool recursing,
- LOCKMODE lockmode)
+ bool check_no_children, LOCKMODE lockmode)
{
List *newcons;
ListCell *lcon;
@@ -5646,14 +5654,24 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
children = find_inheritance_children(RelationGetRelid(rel), lockmode);
/*
- * Check if ONLY was specified with ALTER TABLE. If so, allow the
- * contraint creation only if there are no children currently. Error out
- * otherwise.
+ * Check if either ONLY was specified with ALTER TABLE or if we are adding
+ * back a constraint in AT_PASS_OLD_CONSTR pass, that was previously
+ * dropped constraint. We don't recurse in both the cases.
*/
- if (!recurse && children != NIL)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
- errmsg("constraint must be added to child tables too")));
+ if (!recurse)
+ {
+ /*
+ * We have been told not to recurse. Unless we have been explicitly
+ * told not to check for exitsing children, error out if there are
+ * existing children
+ */
+ if (check_no_children && children != NIL)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
+ errmsg("constraint must be added to child tables too")));
+ else
+ return;
+ }
foreach(child, children)
{
@@ -5670,7 +5688,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
/* Recurse to child */
ATAddCheckConstraint(wqueue, childtab, childrel,
- constr, recurse, true, lockmode);
+ constr, recurse, true, true, lockmode);
heap_close(childrel, NoLock);
}
@@ -7914,6 +7932,7 @@ ATPostAlterTypeParse(Oid oldId, char *cmd,
case AT_AddConstraint:
Assert(IsA(cmd->def, Constraint));
con = (Constraint *) cmd->def;
+ cmd->subtype = AT_ReAddConstraint;
/* rewriting neither side of a FK */
if (con->contype == CONSTR_FOREIGN &&
!rewrite && !tab->rewrite)
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 09b15e7..b58fa82 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1196,6 +1196,7 @@ typedef enum AlterTableType
AT_AddIndex, /* add index */
AT_ReAddIndex, /* internal to commands/tablecmds.c */
AT_AddConstraint, /* add constraint */
+ AT_ReAddConstraint, /* re-add previously dropped constraint */
AT_AddConstraintRecurse, /* internal to commands/tablecmds.c */
AT_ValidateConstraint, /* validate constraint */
AT_ValidateConstraintRecurse, /* internal to commands/tablecmds.c */