Here is a patch for being able to rename constraints of domains.  It
goes on top of the previously committed patch for renaming table
constraints.
diff --git a/doc/src/sgml/ref/alter_domain.sgml b/doc/src/sgml/ref/alter_domain.sgml
index 2511a12..c59975a 100644
--- a/doc/src/sgml/ref/alter_domain.sgml
+++ b/doc/src/sgml/ref/alter_domain.sgml
@@ -32,6 +32,8 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
 ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
     DROP CONSTRAINT [ IF EXISTS ] <replaceable class="PARAMETER">constraint_name</replaceable> [ RESTRICT | CASCADE ]
 ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
+     RENAME CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> TO <replaceable class="PARAMETER">new_constraint_name</replaceable>
+ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
     VALIDATE CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable>
 ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
     OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
@@ -103,6 +105,15 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
    </varlistentry>
 
    <varlistentry>
+    <term>RENAME CONSTRAINT</term>
+    <listitem>
+     <para>
+      This form changes the name of a constraint on a domain.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
     <term>VALIDATE CONSTRAINT</term>
     <listitem>
      <para>
@@ -182,7 +193,7 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
       <term><replaceable class="PARAMETER">constraint_name</replaceable></term>
       <listitem>
        <para>
-        Name of an existing constraint to drop.
+        Name of an existing constraint to drop or rename.
        </para>
       </listitem>
      </varlistentry>
@@ -226,6 +237,15 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
      </varlistentry>
 
      <varlistentry>
+      <term><replaceable class="PARAMETER">new_constraint_name</replaceable></term>
+      <listitem>
+       <para>
+        The new name for the constraint.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
       <term><replaceable class="PARAMETER">new_owner</replaceable></term>
       <listitem>
        <para>
@@ -289,6 +309,13 @@ ALTER DOMAIN zipcode DROP CONSTRAINT zipchk;
   </para>
 
   <para>
+   To rename a check constraint on a domain:
+<programlisting>
+ALTER DOMAIN zipcode RENAME CONSTRAINT zipchk TO zip_check;
+</programlisting>
+  </para>
+
+  <para>
    To move the domain into a different schema:
 <programlisting>
 ALTER DOMAIN zipcode SET SCHEMA customers;
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index e6e0347..08de88b 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -753,7 +753,7 @@ get_object_address_relobject(ObjectType objtype, List *objname,
 			case OBJECT_CONSTRAINT:
 				address.classId = ConstraintRelationId;
 				address.objectId =
-					get_constraint_oid(reloid, depname, missing_ok);
+					get_constraint_oid(reloid, InvalidOid, depname, missing_ok);
 				address.objectSubId = 0;
 				break;
 			default:
diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c
index 342cf75..4377207 100644
--- a/src/backend/catalog/pg_constraint.c
+++ b/src/backend/catalog/pg_constraint.c
@@ -737,17 +737,20 @@ AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
 
 /*
  * get_constraint_oid
- *		Find a constraint on the specified relation with the specified name.
+ *		Find a constraint on the specified relation or domain with the specified name.
  *		Returns constraint's OID.
  */
 Oid
-get_constraint_oid(Oid relid, const char *conname, bool missing_ok)
+get_constraint_oid(Oid relid, Oid typid, const char *conname, bool missing_ok)
 {
 	Relation	pg_constraint;
 	HeapTuple	tuple;
 	SysScanDesc scan;
 	ScanKeyData skey[1];
 	Oid			conOid = InvalidOid;
+	Oid			indexId;
+
+	AssertArg(!relid || !typid);
 
 	/*
 	 * Fetch the constraint tuple from pg_constraint.  There may be more than
@@ -756,12 +759,24 @@ get_constraint_oid(Oid relid, const char *conname, bool missing_ok)
 	 */
 	pg_constraint = heap_open(ConstraintRelationId, AccessShareLock);
 
-	ScanKeyInit(&skey[0],
-				Anum_pg_constraint_conrelid,
-				BTEqualStrategyNumber, F_OIDEQ,
-				ObjectIdGetDatum(relid));
+	if (relid)
+	{
+		ScanKeyInit(&skey[0],
+					Anum_pg_constraint_conrelid,
+					BTEqualStrategyNumber, F_OIDEQ,
+					ObjectIdGetDatum(relid));
+		indexId = ConstraintRelidIndexId;
+	}
+	else
+	{
+		ScanKeyInit(&skey[0],
+					Anum_pg_constraint_contypid,
+					BTEqualStrategyNumber, F_OIDEQ,
+					ObjectIdGetDatum(typid));
+		indexId = ConstraintTypidIndexId;
+	}
 
-	scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true,
+	scan = systable_beginscan(pg_constraint, indexId, true,
 							  SnapshotNow, 1, skey);
 
 	while (HeapTupleIsValid(tuple = systable_getnext(scan)))
@@ -771,10 +786,18 @@ get_constraint_oid(Oid relid, const char *conname, bool missing_ok)
 		if (strcmp(NameStr(con->conname), conname) == 0)
 		{
 			if (OidIsValid(conOid))
-				ereport(ERROR,
-						(errcode(ERRCODE_DUPLICATE_OBJECT),
-				 errmsg("table \"%s\" has multiple constraints named \"%s\"",
-						get_rel_name(relid), conname)));
+			{
+				if (relid)
+					ereport(ERROR,
+							(errcode(ERRCODE_DUPLICATE_OBJECT),
+							 errmsg("table \"%s\" has multiple constraints named \"%s\"",
+									get_rel_name(relid), conname)));
+				else
+					ereport(ERROR,
+							(errcode(ERRCODE_DUPLICATE_OBJECT),
+							 errmsg("domain \"%s\" has multiple constraints named \"%s\"",
+									format_type_be(typid), conname)));
+			}
 			conOid = HeapTupleGetOid(tuple);
 		}
 	}
@@ -783,10 +806,18 @@ get_constraint_oid(Oid relid, const char *conname, bool missing_ok)
 
 	/* If no such constraint exists, complain */
 	if (!OidIsValid(conOid) && !missing_ok)
-		ereport(ERROR,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-				 errmsg("constraint \"%s\" for table \"%s\" does not exist",
-						conname, get_rel_name(relid))));
+	{
+		if (relid)
+			ereport(ERROR,
+					(errcode(ERRCODE_UNDEFINED_OBJECT),
+					 errmsg("constraint \"%s\" for table \"%s\" does not exist",
+							conname, get_rel_name(relid))));
+		else
+			ereport(ERROR,
+					(errcode(ERRCODE_UNDEFINED_OBJECT),
+					 errmsg("constraint \"%s\" for domain \"%s\" does not exist",
+							conname, format_type_be(typid))));
+	}
 
 	heap_close(pg_constraint, AccessShareLock);
 
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 9615380..a0a9270 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -2333,22 +2333,32 @@ renameatt(RenameStmt *stmt)
  */
 static void
 rename_constraint_internal(Oid myrelid,
+						   Oid mytypid,
 						   const char *oldconname,
 						   const char *newconname,
 						   bool recurse,
 						   bool recursing,
 						   int expected_parents)
 {
-	Relation	targetrelation;
+	Relation	targetrelation = NULL;
 	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);
+	AssertArg(!myrelid || !mytypid);
+
+	if (mytypid)
+	{
+		constraintOid = get_constraint_oid(InvalidOid, mytypid, oldconname, false);
+	}
+	else
+	{
+		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);
+		constraintOid = get_constraint_oid(myrelid, InvalidOid, oldconname, false);
+	}
 
 	tuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(constraintOid));
 	if (!HeapTupleIsValid(tuple))
@@ -2356,7 +2366,7 @@ rename_constraint_internal(Oid myrelid,
 			 constraintOid);
 	con = (Form_pg_constraint) GETSTRUCT(tuple);
 
-	if (con->contype == CONSTRAINT_CHECK && !con->conisonly)
+	if (myrelid && con->contype == CONSTRAINT_CHECK && !con->conisonly)
 	{
 		if (recurse)
 		{
@@ -2376,7 +2386,7 @@ rename_constraint_internal(Oid myrelid,
 				if (childrelid == myrelid)
 					continue;
 
-				rename_constraint_internal(childrelid, oldconname, newconname, false, true, numparents);
+				rename_constraint_internal(childrelid, InvalidOid, oldconname, newconname, false, true, numparents);
 			}
 		}
 		else
@@ -2407,24 +2417,43 @@ rename_constraint_internal(Oid myrelid,
 
 	ReleaseSysCache(tuple);
 
-	relation_close(targetrelation, NoLock);		/* close rel but keep lock */
+	if (targetrelation)
+		relation_close(targetrelation, NoLock);		/* close rel but keep lock */
 }
 
 void
 RenameConstraint(RenameStmt *stmt)
 {
-	Oid			relid;
+	Oid			relid = InvalidOid;
+	Oid			typid = InvalidOid;
 
-	/* lock level taken here should match rename_constraint_internal */
-	relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock,
-									 false, false,
-									 RangeVarCallbackForRenameAttribute,
-									 NULL);
+	if (stmt->relationType == OBJECT_DOMAIN)
+	{
+		Relation	rel;
+		HeapTuple	tup;
+
+		typid = typenameTypeId(NULL,  makeTypeNameFromNameList(stmt->object));
+		rel = heap_open(TypeRelationId, RowExclusiveLock);
+		tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
+		if (!HeapTupleIsValid(tup))
+			elog(ERROR, "cache lookup failed for type %u", typid);
+		checkDomainOwner(tup);
+		ReleaseSysCache(tup);
+		heap_close(rel, NoLock);
+	}
+	else
+	{
+		/* lock level taken here should match rename_constraint_internal */
+		relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock,
+										 false, false,
+										 RangeVarCallbackForRenameAttribute,
+										 NULL);
+	}
 
-	rename_constraint_internal(relid,
+	rename_constraint_internal(relid, typid,
 							   stmt->subname,
 							   stmt->newname,
-							   interpretInhOption(stmt->relation->inhOpt),		/* recursive? */
+							   stmt->relation ? interpretInhOption(stmt->relation->inhOpt) : false,		/* recursive? */
 							   false,	/* recursing? */
 							   0		/* expected inhcount */);
 }
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 37fe5e8..701a986 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -98,7 +98,6 @@ static Oid	findRangeCanonicalFunction(List *procname, Oid typeOid);
 static Oid	findRangeSubtypeDiffFunction(List *procname, Oid subtype);
 static void validateDomainConstraint(Oid domainoid, char *ccbin);
 static List *get_rels_with_domain(Oid domainOid, LOCKMODE lockmode);
-static void checkDomainOwner(HeapTuple tup);
 static void checkEnumOwner(HeapTuple tup);
 static char *domainAddConstraint(Oid domainOid, Oid domainNamespace,
 					Oid baseTypeOid,
@@ -2794,7 +2793,7 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode)
  * Check that the type is actually a domain and that the current user
  * has permission to do ALTER DOMAIN on it.  Throw an error if not.
  */
-static void
+void
 checkDomainOwner(HeapTuple tup)
 {
 	Form_pg_type typTup = (Form_pg_type) GETSTRUCT(tup);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index feb28a4..bdfed84 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -6534,6 +6534,16 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
 					n->missing_ok = false;
 					$$ = (Node *)n;
 				}
+			| ALTER DOMAIN_P any_name RENAME CONSTRAINT name TO name
+				{
+					RenameStmt *n = makeNode(RenameStmt);
+					n->renameType = OBJECT_CONSTRAINT;
+					n->relationType = OBJECT_DOMAIN;
+					n->object = $3;
+					n->subname = $6;
+					n->newname = $8;
+					$$ = (Node *)n;
+				}
 			| ALTER FOREIGN DATA_P WRAPPER name RENAME TO name
 				{
 					RenameStmt *n = makeNode(RenameStmt);
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 43f5634..f4370ee 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -802,7 +802,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
 
 			/* Copy comment on constraint */
 			if ((table_like_clause->options & CREATE_TABLE_LIKE_COMMENTS) &&
-				(comment = GetComment(get_constraint_oid(RelationGetRelid(relation),
+				(comment = GetComment(get_constraint_oid(RelationGetRelid(relation), InvalidOid,
 														 n->conname, false),
 									  ConstraintRelationId,
 									  0)) != NULL)
diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h
index 77015ae..19281e5 100644
--- a/src/include/catalog/pg_constraint.h
+++ b/src/include/catalog/pg_constraint.h
@@ -244,7 +244,7 @@ extern char *ChooseConstraintName(const char *name1, const char *name2,
 
 extern void AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
 						  Oid newNspId, bool isType);
-extern Oid	get_constraint_oid(Oid relid, const char *conname, bool missing_ok);
+extern Oid	get_constraint_oid(Oid relid, Oid typid, const char *conname, bool missing_ok);
 
 extern bool check_functional_grouping(Oid relid,
 						  Index varno, Index varlevelsup,
diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h
index 0c7e10d..bb4a7c3 100644
--- a/src/include/commands/typecmds.h
+++ b/src/include/commands/typecmds.h
@@ -14,6 +14,7 @@
 #ifndef TYPECMDS_H
 #define TYPECMDS_H
 
+#include "access/htup.h"
 #include "nodes/parsenodes.h"
 
 
@@ -35,6 +36,8 @@ extern void AlterDomainValidateConstraint(List *names, char *constrName);
 extern void AlterDomainDropConstraint(List *names, const char *constrName,
 									  DropBehavior behavior, bool missing_ok);
 
+extern void checkDomainOwner(HeapTuple tup);
+
 extern List *GetDomainConstraints(Oid typeOid);
 
 extern void RenameType(RenameStmt *stmt);
diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out
index e713b97..03204ff 100644
--- a/src/test/regress/expected/domain.out
+++ b/src/test/regress/expected/domain.out
@@ -659,3 +659,10 @@ create domain testdomain1 as int;
 alter domain testdomain1 rename to testdomain2;
 alter type testdomain2 rename to testdomain3;  -- alter type also works
 drop domain testdomain3;
+--
+-- Renaming domain constraints
+--
+create domain testdomain1 as int constraint unsigned check (value > 0);
+alter domain testdomain1 rename constraint unsigned to unsigned_foo;
+alter domain testdomain1 drop constraint unsigned_foo;
+drop domain testdomain1;
diff --git a/src/test/regress/sql/domain.sql b/src/test/regress/sql/domain.sql
index ad049b7..5af36af 100644
--- a/src/test/regress/sql/domain.sql
+++ b/src/test/regress/sql/domain.sql
@@ -496,3 +496,13 @@ create domain testdomain1 as int;
 alter domain testdomain1 rename to testdomain2;
 alter type testdomain2 rename to testdomain3;  -- alter type also works
 drop domain testdomain3;
+
+
+--
+-- Renaming domain constraints
+--
+
+create domain testdomain1 as int constraint unsigned check (value > 0);
+alter domain testdomain1 rename constraint unsigned to unsigned_foo;
+alter domain testdomain1 drop constraint unsigned_foo;
+drop domain testdomain1;
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to