aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/typecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/typecmds.c')
-rw-r--r--src/backend/commands/typecmds.c54
1 files changed, 51 insertions, 3 deletions
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 915c669c971..5402cde74cd 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.103 2007/05/11 20:16:54 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.104 2007/05/12 00:54:59 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -137,13 +137,27 @@ DefineType(List *names, List *parameters)
/*
* Look to see if type already exists (presumably as a shell; if not,
- * TypeCreate will complain). If it doesn't, create it as a shell, so
- * that the OID is known for use in the I/O function definitions.
+ * TypeCreate will complain).
*/
typoid = GetSysCacheOid(TYPENAMENSP,
CStringGetDatum(typeName),
ObjectIdGetDatum(typeNamespace),
0, 0);
+
+ /*
+ * If it's not a shell, see if it's an autogenerated array type,
+ * and if so rename it out of the way.
+ */
+ if (OidIsValid(typoid) && get_typisdefined(typoid))
+ {
+ if (moveArrayTypeName(typoid, typeName, typeNamespace))
+ typoid = InvalidOid;
+ }
+
+ /*
+ * If it doesn't exist, create it as a shell, so that the OID is known
+ * for use in the I/O function definitions.
+ */
if (!OidIsValid(typoid))
{
typoid = TypeShellMake(typeName, typeNamespace);
@@ -602,6 +616,7 @@ DefineDomain(CreateDomainStmt *stmt)
ListCell *listptr;
Oid basetypeoid;
Oid domainoid;
+ Oid old_type_oid;
Form_pg_type baseType;
int32 basetypeMod;
@@ -617,6 +632,22 @@ DefineDomain(CreateDomainStmt *stmt)
get_namespace_name(domainNamespace));
/*
+ * 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.
+ */
+ old_type_oid = GetSysCacheOid(TYPENAMENSP,
+ CStringGetDatum(domainName),
+ ObjectIdGetDatum(domainNamespace),
+ 0, 0);
+ if (OidIsValid(old_type_oid))
+ {
+ if (!moveArrayTypeName(old_type_oid, domainName, domainNamespace))
+ ereport(ERROR,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("type \"%s\" already exists", domainName)));
+ }
+
+ /*
* Look up the base type.
*/
typeTup = typenameType(NULL, stmt->typename);
@@ -948,6 +979,7 @@ DefineEnum(CreateEnumStmt *stmt)
Oid enumNamespace;
Oid enumTypeOid;
AclResult aclresult;
+ Oid old_type_oid;
Oid enumArrayOid;
Relation pg_type;
@@ -961,6 +993,22 @@ DefineEnum(CreateEnumStmt *stmt)
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
get_namespace_name(enumNamespace));
+ /*
+ * 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.
+ */
+ old_type_oid = GetSysCacheOid(TYPENAMENSP,
+ CStringGetDatum(enumName),
+ ObjectIdGetDatum(enumNamespace),
+ 0, 0);
+ if (OidIsValid(old_type_oid))
+ {
+ if (!moveArrayTypeName(old_type_oid, enumName, enumNamespace))
+ ereport(ERROR,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("type \"%s\" already exists", enumName)));
+ }
+
/* Preassign array type OID so we can insert it in pg_type.typarray */
pg_type = heap_open(TypeRelationId, AccessShareLock);
enumArrayOid = GetNewOid(pg_type);