diff options
Diffstat (limited to 'src/backend/commands/typecmds.c')
-rw-r--r-- | src/backend/commands/typecmds.c | 54 |
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); |