Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Eisentraut2012-03-10 18:19:13 +0000
committerPeter Eisentraut2012-03-10 18:19:13 +0000
commit39d74e346c083aa371ba64c4edb1332c40b56530 (patch)
treea03321b8f8577a7806552f740658b9fe75125cef /src/backend
parente914a144d3aaa0a09e0aab031d7e6f58389401ce (diff)
Add support for renaming constraints
reviewed by Josh Berkus and Dimitri Fontaine
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/commands/alter.c4
-rw-r--r--src/backend/commands/tablecmds.c102
-rw-r--r--src/backend/parser/gram.y10
3 files changed, 116 insertions, 0 deletions
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index 9175405af2a..4dd9927afba 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -57,6 +57,10 @@ ExecRenameStmt(RenameStmt *stmt)
RenameCollation(stmt->object, stmt->newname);
break;
+ case OBJECT_CONSTRAINT:
+ RenameConstraint(stmt);
+ break;
+
case OBJECT_CONVERSION:
RenameConversion(stmt->object, stmt->newname);
break;
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
*/
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 9aea2cd80b5..feb28a41720 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -6731,6 +6731,16 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
n->missing_ok = true;
$$ = (Node *)n;
}
+ | ALTER TABLE relation_expr RENAME CONSTRAINT name TO name
+ {
+ RenameStmt *n = makeNode(RenameStmt);
+ n->renameType = OBJECT_CONSTRAINT;
+ n->relationType = OBJECT_TABLE;
+ n->relation = $3;
+ n->subname = $6;
+ n->newname = $8;
+ $$ = (Node *)n;
+ }
| ALTER FOREIGN TABLE relation_expr RENAME opt_column name TO name
{
RenameStmt *n = makeNode(RenameStmt);