diff options
author | Peter Eisentraut <peter_e@gmx.net> | 2012-03-10 20:19:13 +0200 |
---|---|---|
committer | Peter Eisentraut <peter_e@gmx.net> | 2012-03-10 20:19:13 +0200 |
commit | 39d74e346c083aa371ba64c4edb1332c40b56530 (patch) | |
tree | a03321b8f8577a7806552f740658b9fe75125cef /src/backend/commands/tablecmds.c | |
parent | e914a144d3aaa0a09e0aab031d7e6f58389401ce (diff) | |
download | postgresql-39d74e346c083aa371ba64c4edb1332c40b56530.tar.gz postgresql-39d74e346c083aa371ba64c4edb1332c40b56530.zip |
Add support for renaming constraints
reviewed by Josh Berkus and Dimitri Fontaine
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r-- | src/backend/commands/tablecmds.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 25ca356b867..9615380f05b 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -2327,6 +2327,108 @@ renameatt(RenameStmt *stmt) stmt->behavior); } + +/* + * same logic as renameatt_internal + */ +static void +rename_constraint_internal(Oid myrelid, + const char *oldconname, + const char *newconname, + bool recurse, + bool recursing, + int expected_parents) +{ + Relation targetrelation; + Oid constraintOid; + HeapTuple tuple; + Form_pg_constraint con; + + targetrelation = relation_open(myrelid, AccessExclusiveLock); + /* don't tell it whether we're recursing; we allow changing typed tables here */ + renameatt_check(myrelid, RelationGetForm(targetrelation), false); + + constraintOid = get_constraint_oid(myrelid, oldconname, false); + + tuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(constraintOid)); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for constraint %u", + constraintOid); + con = (Form_pg_constraint) GETSTRUCT(tuple); + + if (con->contype == CONSTRAINT_CHECK && !con->conisonly) + { + if (recurse) + { + List *child_oids, + *child_numparents; + ListCell *lo, + *li; + + child_oids = find_all_inheritors(myrelid, AccessExclusiveLock, + &child_numparents); + + forboth(lo, child_oids, li, child_numparents) + { + Oid childrelid = lfirst_oid(lo); + int numparents = lfirst_int(li); + + if (childrelid == myrelid) + continue; + + rename_constraint_internal(childrelid, oldconname, newconname, false, true, numparents); + } + } + else + { + if (expected_parents == 0 && + find_inheritance_children(myrelid, NoLock) != NIL) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TABLE_DEFINITION), + errmsg("inherited constraint \"%s\" must be renamed in child tables too", + oldconname))); + } + + if (con->coninhcount > expected_parents) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TABLE_DEFINITION), + errmsg("cannot rename inherited constraint \"%s\"", + oldconname))); + } + + if (con->conindid + && (con->contype == CONSTRAINT_PRIMARY + || con->contype == CONSTRAINT_UNIQUE + || con->contype == CONSTRAINT_EXCLUSION)) + /* rename the index; this renames the constraint as well */ + RenameRelationInternal(con->conindid, newconname); + else + RenameConstraintById(constraintOid, newconname); + + ReleaseSysCache(tuple); + + relation_close(targetrelation, NoLock); /* close rel but keep lock */ +} + +void +RenameConstraint(RenameStmt *stmt) +{ + Oid relid; + + /* lock level taken here should match rename_constraint_internal */ + relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock, + false, false, + RangeVarCallbackForRenameAttribute, + NULL); + + rename_constraint_internal(relid, + stmt->subname, + stmt->newname, + interpretInhOption(stmt->relation->inhOpt), /* recursive? */ + false, /* recursing? */ + 0 /* expected inhcount */); +} + /* * Execute ALTER TABLE/INDEX/SEQUENCE/VIEW/FOREIGN TABLE RENAME */ |