From f90dd28062db2128a340fbe02f55829f15ab5561 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Thu, 22 Dec 2011 22:43:56 +0200
Subject: [PATCH] Add ALTER DOMAIN ... RENAME

You could already rename domains using ALTER TYPE, but with this new
command it is more consistent with how other commands treat domains as
a subcategory of types.
---
 doc/src/sgml/ref/alter_domain.sgml   | 22 +++++++++++++++++++++-
 src/backend/commands/alter.c         |  3 ++-
 src/backend/commands/typecmds.c      | 11 ++++++++++-
 src/backend/parser/gram.y            |  8 ++++++++
 src/include/commands/typecmds.h      |  2 +-
 src/test/regress/expected/domain.out |  7 +++++++
 src/test/regress/sql/domain.sql      | 10 ++++++++++
 7 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/doc/src/sgml/ref/alter_domain.sgml b/doc/src/sgml/ref/alter_domain.sgml
index 4f60fe334c0..29504ccd7cb 100644
--- a/doc/src/sgml/ref/alter_domain.sgml
+++ b/doc/src/sgml/ref/alter_domain.sgml
@@ -35,6 +35,8 @@ 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>
+ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
+    RENAME TO <replaceable class="PARAMETER">new_name</replaceable>
 ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
     SET SCHEMA <replaceable class="PARAMETER">new_schema</replaceable>
 </synopsis>
@@ -118,6 +120,15 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
     </listitem>
    </varlistentry>
 
+   <varlistentry>
+    <term><literal>RENAME</literal></term>
+    <listitem>
+     <para>
+      This form changes the name of the domain.
+     </para>
+    </listitem>
+   </varlistentry>
+
    <varlistentry>
     <term>SET SCHEMA</term>
     <listitem>
@@ -203,6 +214,15 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable>
       </listitem>
      </varlistentry>
 
+     <varlistentry>
+      <term><replaceable class="PARAMETER">new_name</replaceable></term>
+      <listitem>
+       <para>
+        The new name for the domain.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <term><replaceable class="PARAMETER">new_owner</replaceable></term>
       <listitem>
@@ -278,7 +298,7 @@ ALTER DOMAIN zipcode SET SCHEMA customers;
 
   <para>
    <command>ALTER DOMAIN</command> conforms to the <acronym>SQL</acronym>
-   standard, except for the <literal>OWNER</>, <literal>SET SCHEMA</> and
+   standard, except for the <literal>OWNER</>, <literal>RENAME</literal>, <literal>SET SCHEMA</>, and
    <literal>VALIDATE CONSTRAINT</> variants, which are
    <productname>PostgreSQL</productname> extensions.  The <literal>NOT VALID</>
    clause of the <literal>ADD CONSTRAINT</> variant is also a
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index 8513837fa10..cc11858d174 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -134,8 +134,9 @@ ExecRenameStmt(RenameStmt *stmt)
 			RenameTSConfiguration(stmt->object, stmt->newname);
 			break;
 
+		case OBJECT_DOMAIN:
 		case OBJECT_TYPE:
-			RenameType(stmt->object, stmt->newname);
+			RenameType(stmt);
 			break;
 
 		default:
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index ea8f7f099a2..811273a01d7 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -3074,8 +3074,10 @@ GetDomainConstraints(Oid typeOid)
  * Execute ALTER TYPE RENAME
  */
 void
-RenameType(List *names, const char *newTypeName)
+RenameType(RenameStmt *stmt)
 {
+	List	   *names = stmt->object;
+	const char *newTypeName = stmt->newname;
 	TypeName   *typename;
 	Oid			typeOid;
 	Relation	rel;
@@ -3099,6 +3101,13 @@ RenameType(List *names, const char *newTypeName)
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE,
 					   format_type_be(typeOid));
 
+	/* ALTER DOMAIN used on a non-domain? */
+	if (stmt->renameType == OBJECT_DOMAIN && typTup->typtype != TYPTYPE_DOMAIN)
+		ereport(ERROR,
+				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
+				 errmsg("\"%s\" is not a domain",
+						format_type_be(typeOid))));
+
 	/*
 	 * If it's a composite type, we need to check that it really is a
 	 * free-standing composite type, and not a table's rowtype. We want people
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index e0ff49f048a..7e8f39abdf7 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -6451,6 +6451,14 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
 					n->newname = $6;
 					$$ = (Node *)n;
 				}
+			| ALTER DOMAIN_P any_name RENAME TO name
+				{
+					RenameStmt *n = makeNode(RenameStmt);
+					n->renameType = OBJECT_DOMAIN;
+					n->object = $3;
+					n->newname = $6;
+					$$ = (Node *)n;
+				}
 			| ALTER FOREIGN DATA_P WRAPPER name RENAME TO name
 				{
 					RenameStmt *n = makeNode(RenameStmt);
diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h
index 0c328958635..0dcbcd6cfb4 100644
--- a/src/include/commands/typecmds.h
+++ b/src/include/commands/typecmds.h
@@ -37,7 +37,7 @@ extern void AlterDomainDropConstraint(List *names, const char *constrName,
 
 extern List *GetDomainConstraints(Oid typeOid);
 
-extern void RenameType(List *names, const char *newTypeName);
+extern void RenameType(RenameStmt *stmt);
 extern void AlterTypeOwner(List *names, Oid newOwnerId);
 extern void AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId,
 					   bool hasDependEntry);
diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out
index 69373efc55b..3e44e3b5331 100644
--- a/src/test/regress/expected/domain.out
+++ b/src/test/regress/expected/domain.out
@@ -648,3 +648,10 @@ select array_elem_check(-1);
 ERROR:  value for domain orderedpair violates check constraint "orderedpair_check"
 CONTEXT:  PL/pgSQL function "array_elem_check" line 5 at assignment
 drop function array_elem_check(int);
+--
+-- Renaming
+--
+create domain testdomain1 as int;
+alter domain testdomain1 rename to testdomain2;
+alter type testdomain2 rename to testdomain3;  -- alter type also works
+drop domain testdomain3;
diff --git a/src/test/regress/sql/domain.sql b/src/test/regress/sql/domain.sql
index 449b4234a5c..1fd39008e68 100644
--- a/src/test/regress/sql/domain.sql
+++ b/src/test/regress/sql/domain.sql
@@ -483,3 +483,13 @@ select array_elem_check(3);
 select array_elem_check(-1);
 
 drop function array_elem_check(int);
+
+
+--
+-- Renaming
+--
+
+create domain testdomain1 as int;
+alter domain testdomain1 rename to testdomain2;
+alter type testdomain2 rename to testdomain3;  -- alter type also works
+drop domain testdomain3;
-- 
GitLab