aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/ref/alter_type.sgml25
-rw-r--r--src/backend/catalog/pg_type.c17
-rw-r--r--src/backend/commands/alter.c8
-rw-r--r--src/backend/commands/tablecmds.c75
-rw-r--r--src/backend/commands/typecmds.c72
-rw-r--r--src/backend/parser/gram.y10
-rw-r--r--src/backend/tcop/utility.c5
-rw-r--r--src/include/catalog/pg_type.h4
-rw-r--r--src/include/commands/tablecmds.h8
-rw-r--r--src/include/commands/typecmds.h3
10 files changed, 180 insertions, 47 deletions
diff --git a/doc/src/sgml/ref/alter_type.sgml b/doc/src/sgml/ref/alter_type.sgml
index c4f9edd399a..6f16da62425 100644
--- a/doc/src/sgml/ref/alter_type.sgml
+++ b/doc/src/sgml/ref/alter_type.sgml
@@ -1,5 +1,5 @@
<!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/alter_type.sgml,v 1.4 2006/09/16 00:30:16 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/alter_type.sgml,v 1.5 2008/03/19 18:38:29 tgl Exp $
PostgreSQL documentation
-->
@@ -24,6 +24,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
+ALTER TYPE <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable class="PARAMETER">new_name</replaceable>
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> SET SCHEMA <replaceable class="PARAMETER">new_schema</replaceable>
</synopsis>
@@ -34,8 +35,6 @@ ALTER TYPE <replaceable class="PARAMETER">name</replaceable> SET SCHEMA <replace
<para>
<command>ALTER TYPE</command> changes the definition of an existing type.
- The only currently available capabilities are changing the owner and schema
- of a type.
</para>
<para>
@@ -66,6 +65,15 @@ ALTER TYPE <replaceable class="PARAMETER">name</replaceable> SET SCHEMA <replace
</varlistentry>
<varlistentry>
+ <term><replaceable class="PARAMETER">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name for the type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><replaceable class="PARAMETER">new_owner</replaceable></term>
<listitem>
<para>
@@ -91,7 +99,14 @@ ALTER TYPE <replaceable class="PARAMETER">name</replaceable> SET SCHEMA <replace
<title>Examples</title>
<para>
- To change the owner of the user-defined type <literal>email</literal>
+ To rename a data type:
+ <programlisting>
+ALTER TYPE electronic_mail RENAME TO email;
+ </programlisting>
+ </para>
+
+ <para>
+ To change the owner of the type <literal>email</literal>
to <literal>joe</literal>:
<programlisting>
ALTER TYPE email OWNER TO joe;
@@ -99,7 +114,7 @@ ALTER TYPE email OWNER TO joe;
</para>
<para>
- To change the schema of the user-defined type <literal>email</literal>
+ To change the schema of the type <literal>email</literal>
to <literal>customers</literal>:
<programlisting>
ALTER TYPE email SET SCHEMA customers;
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index 780d5134d9e..a654f19dbbd 100644
--- a/src/backend/catalog/pg_type.c
+++ b/src/backend/catalog/pg_type.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.115 2008/01/01 19:45:48 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.116 2008/03/19 18:38:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -552,15 +552,16 @@ GenerateTypeDependencies(Oid typeNamespace,
}
/*
- * TypeRename
+ * RenameTypeInternal
* 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.
+ * Caller must have already checked privileges.
+ *
+ * Currently this is used for renaming table rowtypes and for
+ * ALTER TYPE RENAME TO command.
*/
void
-TypeRename(Oid typeOid, const char *newTypeName, Oid typeNamespace)
+RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace)
{
Relation pg_type_desc;
HeapTuple tuple;
@@ -606,7 +607,7 @@ TypeRename(Oid typeOid, const char *newTypeName, Oid typeNamespace)
{
char *arrname = makeArrayTypeName(newTypeName, typeNamespace);
- TypeRename(arrayOid, arrname, typeNamespace);
+ RenameTypeInternal(arrayOid, arrname, typeNamespace);
pfree(arrname);
}
}
@@ -706,7 +707,7 @@ moveArrayTypeName(Oid typeOid, const char *typeName, Oid typeNamespace)
newname = makeArrayTypeName(typeName, typeNamespace);
/* Apply the rename */
- TypeRename(typeOid, newname, typeNamespace);
+ RenameTypeInternal(typeOid, newname, typeNamespace);
/*
* We must bump the command counter so that any subsequent use of
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index 8cf833a9218..63acefa527d 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.27 2008/02/07 21:07:55 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.28 2008/03/19 18:38:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -117,7 +117,7 @@ ExecRenameStmt(RenameStmt *stmt)
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
get_namespace_name(namespaceId));
- renamerel(relid, stmt->newname, stmt->renameType);
+ RenameRelation(relid, stmt->newname, stmt->renameType);
break;
}
case OBJECT_COLUMN:
@@ -154,6 +154,10 @@ ExecRenameStmt(RenameStmt *stmt)
RenameTSConfiguration(stmt->object, stmt->newname);
break;
+ case OBJECT_TYPE:
+ RenameType(stmt->object, stmt->newname);
+ break;
+
default:
elog(ERROR, "unrecognized rename stmt type: %d",
(int) stmt->renameType);
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 027fe51eca4..bd7786a918d 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.242 2008/02/07 17:09:51 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.243 2008/03/19 18:38:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1612,26 +1612,18 @@ renameatt(Oid myrelid,
relation_close(targetrelation, NoLock); /* close rel but keep lock */
}
+
/*
- * renamerel - change the name of a relation
+ * Execute ALTER TABLE/INDEX/SEQUENCE/VIEW RENAME
*
- * 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.
+ * Caller has already done permissions checks.
*/
void
-renamerel(Oid myrelid, const char *newrelname, ObjectType reltype)
+RenameRelation(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 view,
@@ -1639,20 +1631,13 @@ renamerel(Oid myrelid, const char *newrelname, ObjectType reltype)
*/
targetrelation = relation_open(myrelid, AccessExclusiveLock);
- oldrelname = pstrdup(RelationGetRelationName(targetrelation));
namespaceId = RelationGetNamespace(targetrelation);
-
- if (!allowSystemTableMods && IsSystemRelation(targetrelation))
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("permission denied: \"%s\" is a system catalog",
- RelationGetRelationName(targetrelation))));
+ relkind = targetrelation->rd_rel->relkind;
/*
* For compatibility with prior releases, we don't complain if ALTER TABLE
* or ALTER INDEX is used to rename a sequence or view.
*/
- relkind = targetrelation->rd_rel->relkind;
if (reltype == OBJECT_SEQUENCE && relkind != RELKIND_SEQUENCE)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -1665,7 +1650,48 @@ renamerel(Oid myrelid, const char *newrelname, ObjectType reltype)
errmsg("\"%s\" is not a view",
RelationGetRelationName(targetrelation))));
- relhastriggers = (targetrelation->rd_rel->reltriggers > 0);
+ /*
+ * 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 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.
@@ -1703,12 +1729,13 @@ renamerel(Oid myrelid, const char *newrelname, ObjectType reltype)
* Also rename the associated type, if any.
*/
if (OidIsValid(targetrelation->rd_rel->reltype))
- TypeRename(targetrelation->rd_rel->reltype, newrelname, namespaceId);
+ RenameTypeInternal(targetrelation->rd_rel->reltype,
+ newrelname, namespaceId);
/*
* Also rename the associated constraint, if any.
*/
- if (relkind == RELKIND_INDEX)
+ if (targetrelation->rd_rel->relkind == RELKIND_INDEX)
{
Oid constraintId = get_index_constraint(myrelid);
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 9528b58c568..982588e04a6 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.113 2008/01/01 19:45:49 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.114 2008/03/19 18:38:30 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -2339,6 +2339,76 @@ GetDomainConstraints(Oid typeOid)
return result;
}
+
+/*
+ * 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, NULL);
+
+ /* 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",
+ format_type_be(typeOid)),
+ errhint("Use ALTER TABLE instead.")));
+
+ /* 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 we need to rename associated pg_class entry 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);
+}
+
/*
* Change the owner of a type.
*/
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 4688bc79778..6d4df81a8a3 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.607 2008/02/15 22:17:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.608 2008/03/19 18:38:30 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -4734,6 +4734,14 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
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; }
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index fbd8f0d5643..df3887b1dc9 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.290 2008/03/14 17:25:58 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.291 2008/03/19 18:38:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1613,6 +1613,9 @@ CreateCommandTag(Node *parsetree)
case OBJECT_TSCONFIGURATION:
tag = "ALTER TEXT SEARCH CONFIGURATION";
break;
+ case OBJECT_TYPE:
+ tag = "ALTER TYPE";
+ break;
default:
tag = "???";
break;
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index 7ece0af78c2..961f35e5897 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.191 2008/01/01 19:45:57 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.192 2008/03/19 18:38:30 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -682,7 +682,7 @@ extern void GenerateTypeDependencies(Oid typeNamespace,
Node *defaultExpr,
bool rebuild);
-extern void TypeRename(Oid typeOid, const char *newTypeName,
+extern void RenameTypeInternal(Oid typeOid, const char *newTypeName,
Oid typeNamespace);
extern char *makeArrayTypeName(const char *typeName, Oid typeNamespace);
diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h
index e9c965439ce..700c1bd42ef 100644
--- a/src/include/commands/tablecmds.h
+++ b/src/include/commands/tablecmds.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/commands/tablecmds.h,v 1.37 2008/01/30 19:46:48 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/commands/tablecmds.h,v 1.38 2008/03/19 18:38:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -44,10 +44,14 @@ extern void renameatt(Oid myrelid,
bool recurse,
bool recursing);
-extern void renamerel(Oid myrelid,
+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);
diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h
index 71d0ceefa81..ce807b56d08 100644
--- a/src/include/commands/typecmds.h
+++ b/src/include/commands/typecmds.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/commands/typecmds.h,v 1.22 2008/01/01 19:45:57 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/commands/typecmds.h,v 1.23 2008/03/19 18:38:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -35,6 +35,7 @@ extern void AlterDomainDropConstraint(List *names, const char *constrName,
extern List *GetDomainConstraints(Oid typeOid);
+extern void RenameType(List *names, const char *newTypeName);
extern void AlterTypeOwner(List *names, Oid newOwnerId);
extern void AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId,
bool hasDependEntry);