diff options
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r-- | src/backend/commands/tablecmds.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 75bdf7ba0c4..a7497e5c2a5 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -3390,7 +3390,7 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, case AT_ReAddConstraint: /* Re-add pre-existing check * constraint */ ATExecAddConstraint(wqueue, tab, rel, (Constraint *) cmd->def, - false, true, lockmode); + true, true, lockmode); break; case AT_AddIndexConstraint: /* ADD CONSTRAINT USING INDEX */ ATExecAddIndexConstraint(tab, rel, (IndexStmt *) cmd->def, lockmode); @@ -5764,13 +5764,6 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, * AddRelationNewConstraints would normally assign different names to the * child constraints. To fix that, we must capture the name assigned at * the parent table and pass that down. - * - * When re-adding a previously existing constraint (during ALTER COLUMN TYPE), - * we don't need to recurse here, because recursion will be carried out at a - * higher level; the constraint name issue doesn't apply because the names - * have already been assigned and are just being re-used. We need a separate - * "is_readd" flag for that; just setting recurse=false would result in an - * error if there are child tables. */ static void ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, @@ -5798,7 +5791,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, */ newcons = AddRelationNewConstraints(rel, NIL, list_make1(copyObject(constr)), - recursing, /* allow_merge */ + recursing | is_readd, /* allow_merge */ !recursing, /* is_local */ is_readd); /* is_internal */ @@ -5842,10 +5835,8 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, /* * If adding a NO INHERIT constraint, no need to find our children. - * Likewise, in a re-add operation, we don't need to recurse (that will be - * handled at higher levels). */ - if (constr->is_no_inherit || is_readd) + if (constr->is_no_inherit) return; /* @@ -8204,10 +8195,30 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) def_item, tab->changedConstraintDefs) { Oid oldId = lfirst_oid(oid_item); + HeapTuple tup; + Form_pg_constraint con; Oid relid; Oid confrelid; + bool conislocal; + + tup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(oldId)); + if (!HeapTupleIsValid(tup)) /* should not happen */ + elog(ERROR, "cache lookup failed for constraint %u", oldId); + con = (Form_pg_constraint) GETSTRUCT(tup); + relid = con->conrelid; + confrelid = con->confrelid; + conislocal = con->conislocal; + ReleaseSysCache(tup); + + /* + * If the constraint is inherited (only), we don't want to inject a + * new definition here; it'll get recreated when ATAddCheckConstraint + * recurses from adding the parent table's constraint. But we had to + * carry the info this far so that we can drop the constraint below. + */ + if (!conislocal) + continue; - get_constraint_relation_oids(oldId, &relid, &confrelid); ATPostAlterTypeParse(oldId, relid, confrelid, (char *) lfirst(def_item), wqueue, lockmode, tab->rewrite); |