From eb210ce85a6326412f2a35eb416d92801cfe997d Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Wed, 20 Jan 2010 05:47:09 +0000
Subject: [PATCH] Before attempting to create a composite type, check whether a
 type of that name already exists, so we'd get an error message about a "type"
 instead of about a "relation", because the composite type code shares code
 with relation creation.

---
 src/backend/commands/typecmds.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 4b38fe957c7..7d5b409f59e 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.145 2010/01/02 16:57:39 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.146 2010/01/20 05:47:09 petere Exp $
  *
  * DESCRIPTION
  *	  The "DefineFoo" routines take the parse tree and pick out the
@@ -1509,6 +1509,8 @@ Oid
 DefineCompositeType(const RangeVar *typevar, List *coldeflist)
 {
 	CreateStmt *createStmt = makeNode(CreateStmt);
+	Oid			old_type_oid;
+	Oid			typeNamespace;
 
 	if (coldeflist == NIL)
 		ereport(ERROR,
@@ -1528,7 +1530,26 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist)
 	createStmt->tablespacename = NULL;
 
 	/*
-	 * finally create the relation...
+	 * Check for collision with an existing type name. If there is one
+	 * and it's an autogenerated array, we can rename it out of the
+	 * way.  This check is here mainly to get a better error message
+	 * about a "type" instead of below about a "relation".
+	 */
+	typeNamespace = RangeVarGetCreationNamespace(createStmt->relation);
+	old_type_oid = GetSysCacheOid(TYPENAMENSP,
+								  CStringGetDatum(createStmt->relation->relname),
+								  ObjectIdGetDatum(typeNamespace),
+								  0, 0);
+	if (OidIsValid(old_type_oid))
+	{
+		if (!moveArrayTypeName(old_type_oid, createStmt->relation->relname, typeNamespace))
+			ereport(ERROR,
+					(errcode(ERRCODE_DUPLICATE_OBJECT),
+					 errmsg("type \"%s\" already exists", createStmt->relation->relname)));
+	}
+
+	/*
+	 * Finally create the relation.  This also creates the type.
 	 */
 	return DefineRelation(createStmt, RELKIND_COMPOSITE_TYPE);
 }
-- 
GitLab