Index: doc/src/sgml/ref/alter_type.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/alter_type.sgml,v
retrieving revision 1.4
diff -c -r1.4 alter_type.sgml
*** doc/src/sgml/ref/alter_type.sgml 16 Sep 2006 00:30:16 -0000 1.4
--- doc/src/sgml/ref/alter_type.sgml 29 Sep 2007 05:43:14 -0000
***************
*** 26,31 ****
--- 26,32 ----
ALTER TYPE name OWNER TO new_owner
ALTER TYPE name SET SCHEMA new_schema
+ ALTER TYPE name RNAME TO new_name
***************
*** 83,88 ****
--- 84,98 ----
+
+ new_name
+
+
+ The new name for the type.
+
+
+
+
Index: src/backend/catalog/pg_type.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/pg_type.c,v
retrieving revision 1.113
diff -c -r1.113 pg_type.c
*** src/backend/catalog/pg_type.c 12 May 2007 00:54:59 -0000 1.113
--- src/backend/catalog/pg_type.c 30 Sep 2007 04:20:03 -0000
***************
*** 552,566 ****
}
/*
! * TypeRename
* This renames a type, as well as any associated array type.
*
! * Note: this isn't intended to be a user-exposed function; it doesn't check
! * permissions etc. (Perhaps TypeRenameInternal would be a better name.)
! * Currently this is only used for renaming table rowtypes.
*/
void
! TypeRename(Oid typeOid, const char *newTypeName, Oid typeNamespace)
{
Relation pg_type_desc;
HeapTuple tuple;
--- 552,567 ----
}
/*
! * RenameTypeInternal
* This renames a type, as well as any associated array type.
*
! * Caller must have already checked privileges.
! *
! * Currently this is used for renaming table rowtypes and for
! * ALTER TYPE RENAME TO command.
*/
void
! RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace)
{
Relation pg_type_desc;
HeapTuple tuple;
***************
*** 606,612 ****
{
char *arrname = makeArrayTypeName(newTypeName, typeNamespace);
! TypeRename(arrayOid, arrname, typeNamespace);
pfree(arrname);
}
}
--- 607,613 ----
{
char *arrname = makeArrayTypeName(newTypeName, typeNamespace);
! RenameTypeInternal(arrayOid, arrname, typeNamespace);
pfree(arrname);
}
}
***************
*** 706,712 ****
newname = makeArrayTypeName(typeName, typeNamespace);
/* Apply the rename */
! TypeRename(typeOid, newname, typeNamespace);
/*
* We must bump the command counter so that any subsequent use of
--- 707,713 ----
newname = makeArrayTypeName(typeName, typeNamespace);
/* Apply the rename */
! RenameTypeInternal(typeOid, newname, typeNamespace);
/*
* We must bump the command counter so that any subsequent use of
Index: src/backend/commands/alter.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/alter.c,v
retrieving revision 1.25
diff -c -r1.25 alter.c
*** src/backend/commands/alter.c 21 Aug 2007 01:11:14 -0000 1.25
--- src/backend/commands/alter.c 30 Sep 2007 03:53:05 -0000
***************
*** 117,123 ****
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
get_namespace_name(namespaceId));
! renamerel(relid, stmt->newname, stmt->renameType);
break;
}
case OBJECT_COLUMN:
--- 117,123 ----
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
get_namespace_name(namespaceId));
! RenameRelation(relid, stmt->newname, stmt->renameType);
break;
}
case OBJECT_COLUMN:
***************
*** 154,159 ****
--- 154,164 ----
RenameTSConfiguration(stmt->object, stmt->newname);
break;
+ case OBJECT_TYPE:
+ case OBJECT_DOMAIN:
+ RenameType(stmt->object, stmt->newname);
+ break;
+
default:
elog(ERROR, "unrecognized rename stmt type: %d",
(int) stmt->renameType);
Index: src/backend/commands/tablecmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/tablecmds.c,v
retrieving revision 1.233
diff -c -r1.233 tablecmds.c
*** src/backend/commands/tablecmds.c 29 Sep 2007 17:18:58 -0000 1.233
--- src/backend/commands/tablecmds.c 30 Sep 2007 03:55:31 -0000
***************
*** 1612,1637 ****
relation_close(targetrelation, NoLock); /* close rel but keep lock */
}
/*
! * renamerel - change the name of a relation
! *
! * XXX - When renaming sequences, we don't bother to modify the
! * sequence name that is stored within the sequence itself
! * (this would cause problems with MVCC). In the future,
! * the sequence name should probably be removed from the
! * sequence, AFAIK there's no need for it to be there.
*/
void
! renamerel(Oid myrelid, const char *newrelname, ObjectType reltype)
{
Relation targetrelation;
- Relation relrelation; /* for RELATION relation */
- HeapTuple reltup;
- Form_pg_class relform;
Oid namespaceId;
- char *oldrelname;
char relkind;
- bool relhastriggers;
/*
* Grab an exclusive lock on the target table, index, sequence or
--- 1612,1627 ----
relation_close(targetrelation, NoLock); /* close rel but keep lock */
}
+
/*
! * Execute ALTER TABLE/VIEW/SEQUENCE RENAME
*/
void
! RenameRelation(Oid myrelid, const char *newrelname, ObjectType reltype)
{
Relation targetrelation;
Oid namespaceId;
char relkind;
/*
* Grab an exclusive lock on the target table, index, sequence or
***************
*** 1639,1645 ****
*/
targetrelation = relation_open(myrelid, AccessExclusiveLock);
- oldrelname = pstrdup(RelationGetRelationName(targetrelation));
namespaceId = RelationGetNamespace(targetrelation);
if (!allowSystemTableMods && IsSystemRelation(targetrelation))
--- 1629,1634 ----
***************
*** 1654,1672 ****
* view.
*/
relkind = targetrelation->rd_rel->relkind;
! if (reltype == OBJECT_SEQUENCE && relkind != 'S')
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("\"%s\" is not a sequence",
RelationGetRelationName(targetrelation))));
! if (reltype == OBJECT_VIEW && relkind != 'v')
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("\"%s\" is not a view",
RelationGetRelationName(targetrelation))));
! relhastriggers = (targetrelation->rd_rel->reltriggers > 0);
/*
* Find relation's pg_class tuple, and make sure newrelname isn't in use.
--- 1643,1702 ----
* view.
*/
relkind = targetrelation->rd_rel->relkind;
! if (reltype == OBJECT_SEQUENCE && relkind != RELKIND_SEQUENCE)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("\"%s\" is not a sequence",
RelationGetRelationName(targetrelation))));
! if (reltype == OBJECT_VIEW && relkind != RELKIND_VIEW)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("\"%s\" is not a view",
RelationGetRelationName(targetrelation))));
! /*
! * Don't allow ALTER TABLE on composite types.
! * We want people to use ALTER TYPE for that.
! */
! if (relkind == RELKIND_COMPOSITE_TYPE)
! ereport(ERROR,
! (errcode(ERRCODE_WRONG_OBJECT_TYPE),
! errmsg("\"%s\" is a composite type",
! RelationGetRelationName(targetrelation)),
! errhint("Use ALTER TYPE RENAME TO instead.")));
!
! /* Do the work */
! RenameRelationInternal(myrelid, newrelname, namespaceId);
!
! /*
! * Close rel, but keep exclusive lock!
! */
! relation_close(targetrelation, NoLock);
! }
!
! /*
! * RenameRelationInternal - change the name of a relation
! *
! * XXX - When renaming sequences, we don't bother to modify the
! * sequence name that is stored within the sequence itself
! * (this would cause problems with MVCC). In the future,
! * the sequence name should probably be removed from the
! * sequence, AFAIK there's no need for it to be there.
! */
! void
! RenameRelationInternal(Oid myrelid, const char *newrelname, Oid namespaceId)
! {
! Relation targetrelation;
! Relation relrelation; /* for RELATION relation */
! HeapTuple reltup;
! Form_pg_class relform;
!
! /*
! * Grab an exclusive lock on the target table, index, sequence or
! * view, which we will NOT release until end of transaction.
! */
! targetrelation = relation_open(myrelid, AccessExclusiveLock);
/*
* Find relation's pg_class tuple, and make sure newrelname isn't in use.
***************
*** 1704,1710 ****
* Also rename the associated type, if any.
*/
if (OidIsValid(targetrelation->rd_rel->reltype))
! TypeRename(targetrelation->rd_rel->reltype, newrelname, namespaceId);
/*
* Close rel, but keep exclusive lock!
--- 1734,1740 ----
* Also rename the associated type, if any.
*/
if (OidIsValid(targetrelation->rd_rel->reltype))
! RenameTypeInternal(targetrelation->rd_rel->reltype, newrelname, namespaceId);
/*
* Close rel, but keep exclusive lock!
Index: src/backend/commands/typecmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/typecmds.c,v
retrieving revision 1.108
diff -c -r1.108 typecmds.c
*** src/backend/commands/typecmds.c 29 Sep 2007 17:18:58 -0000 1.108
--- src/backend/commands/typecmds.c 30 Sep 2007 04:36:08 -0000
***************
*** 2654,2656 ****
--- 2654,2723 ----
if (OidIsValid(arrayOid))
AlterTypeNamespaceInternal(arrayOid, nspOid, true, true);
}
+
+
+ /*
+ * Execute ALTER TYPE RENAME
+ */
+ void
+ RenameType(List *names, const char *newTypeName)
+ {
+ TypeName *typename;
+ Oid typeOid;
+ Relation rel;
+ HeapTuple tup;
+ Form_pg_type typTup;
+
+ /* Make a TypeName so we can use standard type lookup machinery */
+ typename = makeTypeNameFromNameList(names);
+ typeOid = typenameTypeId(NULL, typename);
+
+ /* Look up the type in the type table */
+ rel = heap_open(TypeRelationId, RowExclusiveLock);
+
+ tup = SearchSysCacheCopy(TYPEOID,
+ ObjectIdGetDatum(typeOid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for type %u", typeOid);
+ typTup = (Form_pg_type) GETSTRUCT(tup);
+
+ /* check permissions on type */
+ if (!pg_type_ownercheck(typeOid, GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE,
+ format_type_be(typeOid));
+
+ /*
+ * If it's a composite type, we need to check that it really is a
+ * free-standing composite type, and not a table's rowtype. We
+ * want people to use ALTER TABLE not ALTER TYPE for that case.
+ */
+ if (typTup->typtype == TYPTYPE_COMPOSITE &&
+ get_rel_relkind(typTup->typrelid) != RELKIND_COMPOSITE_TYPE)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is a table's row type",
+ TypeNameToString(typename))));
+
+ /* don't allow direct alteration of array types, either */
+ if (OidIsValid(typTup->typelem) &&
+ get_array_type(typTup->typelem) == typeOid)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot alter array type %s",
+ format_type_be(typeOid)),
+ errhint("You can alter type %s, which will alter the array type as well.",
+ format_type_be(typTup->typelem))));
+
+ /*
+ * If type is composite type we need to rename associated relation too.
+ * RenameRelationInternal will call RenameTypeInternal automatically.
+ */
+ if (typTup->typtype == TYPTYPE_COMPOSITE)
+ RenameRelationInternal(typTup->typrelid, newTypeName, typTup->typnamespace);
+ else
+ RenameTypeInternal(typeOid, newTypeName, typTup->typnamespace);
+
+ /* Clean up */
+ heap_close(rel, RowExclusiveLock);
+ }
Index: src/backend/parser/gram.y
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.603
diff -c -r2.603 gram.y
*** src/backend/parser/gram.y 24 Sep 2007 01:29:28 -0000 2.603
--- src/backend/parser/gram.y 29 Sep 2007 05:13:21 -0000
***************
*** 4748,4753 ****
--- 4748,4761 ----
n->newname = $8;
$$ = (Node *)n;
}
+ | ALTER TYPE_P any_name RENAME TO name
+ {
+ RenameStmt *n = makeNode(RenameStmt);
+ n->renameType = OBJECT_TYPE;
+ n->object = $3;
+ n->newname = $6;
+ $$ = (Node *)n;
+ }
;
opt_column: COLUMN { $$ = COLUMN; }
Index: src/include/catalog/pg_type.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_type.h,v
retrieving revision 1.188
diff -c -r1.188 pg_type.h
*** src/include/catalog/pg_type.h 3 Sep 2007 02:30:45 -0000 1.188
--- src/include/catalog/pg_type.h 29 Sep 2007 23:04:57 -0000
***************
*** 678,684 ****
Node *defaultExpr,
bool rebuild);
! extern void TypeRename(Oid typeOid, const char *newTypeName,
Oid typeNamespace);
extern char *makeArrayTypeName(const char *typeName, Oid typeNamespace);
--- 678,684 ----
Node *defaultExpr,
bool rebuild);
! extern void RenameTypeInternal(Oid typeOid, const char *newTypeName,
Oid typeNamespace);
extern char *makeArrayTypeName(const char *typeName, Oid typeNamespace);
Index: src/include/commands/tablecmds.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/commands/tablecmds.h,v
retrieving revision 1.34
diff -c -r1.34 tablecmds.h
*** src/include/commands/tablecmds.h 3 Jul 2007 01:30:37 -0000 1.34
--- src/include/commands/tablecmds.h 30 Sep 2007 03:49:44 -0000
***************
*** 42,51 ****
bool recurse,
bool recursing);
! extern void renamerel(Oid myrelid,
const char *newrelname,
ObjectType reltype);
extern void find_composite_type_dependencies(Oid typeOid,
const char *origTblName,
const char *origTypeName);
--- 42,55 ----
bool recurse,
bool recursing);
! extern void RenameRelation(Oid myrelid,
const char *newrelname,
ObjectType reltype);
+ extern void RenameRelationInternal(Oid myrelid,
+ const char *newrelname,
+ Oid namespaceId);
+
extern void find_composite_type_dependencies(Oid typeOid,
const char *origTblName,
const char *origTypeName);
Index: src/include/commands/typecmds.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/commands/typecmds.h,v
retrieving revision 1.19
diff -c -r1.19 typecmds.h
*** src/include/commands/typecmds.h 11 May 2007 17:57:14 -0000 1.19
--- src/include/commands/typecmds.h 29 Sep 2007 05:11:57 -0000
***************
*** 43,46 ****
--- 43,48 ----
bool isImplicitArray,
bool errorOnTableType);
+ extern void RenameType(List *names, const char *newTypeName);
+
#endif /* TYPECMDS_H */