]> granicus.if.org Git - postgresql/commitdiff
Before attempting to create a composite type, check whether a type of that
authorPeter Eisentraut <peter_e@gmx.net>
Wed, 20 Jan 2010 05:47:09 +0000 (05:47 +0000)
committerPeter Eisentraut <peter_e@gmx.net>
Wed, 20 Jan 2010 05:47:09 +0000 (05:47 +0000)
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

index 4b38fe957c7ef277ed1fb62df2de890703243e7c..7d5b409f59e9007360462df61526bc2721dcca7a 100644 (file)
@@ -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);
 }