mirror of
https://github.com/postgres/postgres.git
synced 2025-07-17 06:41:09 +03:00
Fix the problem that creating a user-defined type named _foo, followed by one
named foo, would work but the other ordering would not. If a user-specified type or table name collides with an existing auto-generated array name, just rename the array type out of the way by prepending more underscores. This should not create any backward-compatibility issues, since the cases in which this will happen would have failed outright in prior releases. Also fix an oversight in the arrays-of-composites patch: ALTER TABLE RENAME renamed the table's rowtype but not its array type.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.221 2007/05/11 20:16:36 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.222 2007/05/12 00:54:59 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1626,6 +1626,7 @@ renamerel(Oid myrelid, const char *newrelname)
|
||||
Relation targetrelation;
|
||||
Relation relrelation; /* for RELATION relation */
|
||||
HeapTuple reltup;
|
||||
Form_pg_class relform;
|
||||
Oid namespaceId;
|
||||
char *oldrelname;
|
||||
char relkind;
|
||||
@ -1655,10 +1656,11 @@ renamerel(Oid myrelid, const char *newrelname)
|
||||
relrelation = heap_open(RelationRelationId, RowExclusiveLock);
|
||||
|
||||
reltup = SearchSysCacheCopy(RELOID,
|
||||
PointerGetDatum(myrelid),
|
||||
ObjectIdGetDatum(myrelid),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(reltup)) /* shouldn't happen */
|
||||
elog(ERROR, "cache lookup failed for relation %u", myrelid);
|
||||
relform = (Form_pg_class) GETSTRUCT(reltup);
|
||||
|
||||
if (get_relname_relid(newrelname, namespaceId) != InvalidOid)
|
||||
ereport(ERROR,
|
||||
@ -1670,7 +1672,7 @@ renamerel(Oid myrelid, const char *newrelname)
|
||||
* Update pg_class tuple with new relname. (Scribbling on reltup is OK
|
||||
* because it's a copy...)
|
||||
*/
|
||||
namestrcpy(&(((Form_pg_class) GETSTRUCT(reltup))->relname), newrelname);
|
||||
namestrcpy(&(relform->relname), newrelname);
|
||||
|
||||
simple_heap_update(relrelation, &reltup->t_self, reltup);
|
||||
|
||||
@ -1683,8 +1685,8 @@ renamerel(Oid myrelid, const char *newrelname)
|
||||
/*
|
||||
* Also rename the associated type, if any.
|
||||
*/
|
||||
if (relkind != RELKIND_INDEX)
|
||||
TypeRename(oldrelname, namespaceId, newrelname);
|
||||
if (OidIsValid(targetrelation->rd_rel->reltype))
|
||||
TypeRename(targetrelation->rd_rel->reltype, newrelname, namespaceId);
|
||||
|
||||
/*
|
||||
* Close rel, but keep exclusive lock!
|
||||
|
@ -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;
|
||||
|
||||
@ -616,6 +631,22 @@ DefineDomain(CreateDomainStmt *stmt)
|
||||
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
|
||||
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.
|
||||
*/
|
||||
@ -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);
|
||||
|
Reference in New Issue
Block a user