Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5507b22

Browse files
committed
Support ALTER TYPE RENAME. Petr Jelinek
1 parent a968659 commit 5507b22

File tree

10 files changed

+180
-47
lines changed

10 files changed

+180
-47
lines changed

doc/src/sgml/ref/alter_type.sgml

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_type.sgml,v 1.4 2006/09/16 00:30:16 momjian Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_type.sgml,v 1.5 2008/03/19 18:38:29 tgl Exp $
33
PostgreSQL documentation
44
-->
55

@@ -24,6 +24,7 @@ PostgreSQL documentation
2424

2525
<refsynopsisdiv>
2626
<synopsis>
27+
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable class="PARAMETER">new_name</replaceable>
2728
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
2829
ALTER TYPE <replaceable class="PARAMETER">name</replaceable> SET SCHEMA <replaceable class="PARAMETER">new_schema</replaceable>
2930
</synopsis>
@@ -34,8 +35,6 @@ ALTER TYPE <replaceable class="PARAMETER">name</replaceable> SET SCHEMA <replace
3435

3536
<para>
3637
<command>ALTER TYPE</command> changes the definition of an existing type.
37-
The only currently available capabilities are changing the owner and schema
38-
of a type.
3938
</para>
4039

4140
<para>
@@ -65,6 +64,15 @@ ALTER TYPE <replaceable class="PARAMETER">name</replaceable> SET SCHEMA <replace
6564
</listitem>
6665
</varlistentry>
6766

67+
<varlistentry>
68+
<term><replaceable class="PARAMETER">new_name</replaceable></term>
69+
<listitem>
70+
<para>
71+
The new name for the type.
72+
</para>
73+
</listitem>
74+
</varlistentry>
75+
6876
<varlistentry>
6977
<term><replaceable class="PARAMETER">new_owner</replaceable></term>
7078
<listitem>
@@ -91,15 +99,22 @@ ALTER TYPE <replaceable class="PARAMETER">name</replaceable> SET SCHEMA <replace
9199
<title>Examples</title>
92100

93101
<para>
94-
To change the owner of the user-defined type <literal>email</literal>
102+
To rename a data type:
103+
<programlisting>
104+
ALTER TYPE electronic_mail RENAME TO email;
105+
</programlisting>
106+
</para>
107+
108+
<para>
109+
To change the owner of the type <literal>email</literal>
95110
to <literal>joe</literal>:
96111
<programlisting>
97112
ALTER TYPE email OWNER TO joe;
98113
</programlisting>
99114
</para>
100115

101116
<para>
102-
To change the schema of the user-defined type <literal>email</literal>
117+
To change the schema of the type <literal>email</literal>
103118
to <literal>customers</literal>:
104119
<programlisting>
105120
ALTER TYPE email SET SCHEMA customers;

src/backend/catalog/pg_type.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.115 2008/01/01 19:45:48 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.116 2008/03/19 18:38:30 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -552,15 +552,16 @@ GenerateTypeDependencies(Oid typeNamespace,
552552
}
553553

554554
/*
555-
* TypeRename
555+
* RenameTypeInternal
556556
* This renames a type, as well as any associated array type.
557557
*
558-
* Note: this isn't intended to be a user-exposed function; it doesn't check
559-
* permissions etc. (Perhaps TypeRenameInternal would be a better name.)
560-
* Currently this is only used for renaming table rowtypes.
558+
* Caller must have already checked privileges.
559+
*
560+
* Currently this is used for renaming table rowtypes and for
561+
* ALTER TYPE RENAME TO command.
561562
*/
562563
void
563-
TypeRename(Oid typeOid, const char *newTypeName, Oid typeNamespace)
564+
RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace)
564565
{
565566
Relation pg_type_desc;
566567
HeapTuple tuple;
@@ -606,7 +607,7 @@ TypeRename(Oid typeOid, const char *newTypeName, Oid typeNamespace)
606607
{
607608
char *arrname = makeArrayTypeName(newTypeName, typeNamespace);
608609

609-
TypeRename(arrayOid, arrname, typeNamespace);
610+
RenameTypeInternal(arrayOid, arrname, typeNamespace);
610611
pfree(arrname);
611612
}
612613
}
@@ -706,7 +707,7 @@ moveArrayTypeName(Oid typeOid, const char *typeName, Oid typeNamespace)
706707
newname = makeArrayTypeName(typeName, typeNamespace);
707708

708709
/* Apply the rename */
709-
TypeRename(typeOid, newname, typeNamespace);
710+
RenameTypeInternal(typeOid, newname, typeNamespace);
710711

711712
/*
712713
* We must bump the command counter so that any subsequent use of

src/backend/commands/alter.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.27 2008/02/07 21:07:55 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.28 2008/03/19 18:38:30 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -117,7 +117,7 @@ ExecRenameStmt(RenameStmt *stmt)
117117
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
118118
get_namespace_name(namespaceId));
119119

120-
renamerel(relid, stmt->newname, stmt->renameType);
120+
RenameRelation(relid, stmt->newname, stmt->renameType);
121121
break;
122122
}
123123
case OBJECT_COLUMN:
@@ -154,6 +154,10 @@ ExecRenameStmt(RenameStmt *stmt)
154154
RenameTSConfiguration(stmt->object, stmt->newname);
155155
break;
156156

157+
case OBJECT_TYPE:
158+
RenameType(stmt->object, stmt->newname);
159+
break;
160+
157161
default:
158162
elog(ERROR, "unrecognized rename stmt type: %d",
159163
(int) stmt->renameType);

src/backend/commands/tablecmds.c

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.242 2008/02/07 17:09:51 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.243 2008/03/19 18:38:30 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1612,47 +1612,32 @@ renameatt(Oid myrelid,
16121612
relation_close(targetrelation, NoLock); /* close rel but keep lock */
16131613
}
16141614

1615+
16151616
/*
1616-
* renamerel - change the name of a relation
1617+
* Execute ALTER TABLE/INDEX/SEQUENCE/VIEW RENAME
16171618
*
1618-
* XXX - When renaming sequences, we don't bother to modify the
1619-
* sequence name that is stored within the sequence itself
1620-
* (this would cause problems with MVCC). In the future,
1621-
* the sequence name should probably be removed from the
1622-
* sequence, AFAIK there's no need for it to be there.
1619+
* Caller has already done permissions checks.
16231620
*/
16241621
void
1625-
renamerel(Oid myrelid, const char *newrelname, ObjectType reltype)
1622+
RenameRelation(Oid myrelid, const char *newrelname, ObjectType reltype)
16261623
{
16271624
Relation targetrelation;
1628-
Relation relrelation; /* for RELATION relation */
1629-
HeapTuple reltup;
1630-
Form_pg_class relform;
16311625
Oid namespaceId;
1632-
char *oldrelname;
16331626
char relkind;
1634-
bool relhastriggers;
16351627

16361628
/*
16371629
* Grab an exclusive lock on the target table, index, sequence or view,
16381630
* which we will NOT release until end of transaction.
16391631
*/
16401632
targetrelation = relation_open(myrelid, AccessExclusiveLock);
16411633

1642-
oldrelname = pstrdup(RelationGetRelationName(targetrelation));
16431634
namespaceId = RelationGetNamespace(targetrelation);
1644-
1645-
if (!allowSystemTableMods && IsSystemRelation(targetrelation))
1646-
ereport(ERROR,
1647-
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1648-
errmsg("permission denied: \"%s\" is a system catalog",
1649-
RelationGetRelationName(targetrelation))));
1635+
relkind = targetrelation->rd_rel->relkind;
16501636

16511637
/*
16521638
* For compatibility with prior releases, we don't complain if ALTER TABLE
16531639
* or ALTER INDEX is used to rename a sequence or view.
16541640
*/
1655-
relkind = targetrelation->rd_rel->relkind;
16561641
if (reltype == OBJECT_SEQUENCE && relkind != RELKIND_SEQUENCE)
16571642
ereport(ERROR,
16581643
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -1665,7 +1650,48 @@ renamerel(Oid myrelid, const char *newrelname, ObjectType reltype)
16651650
errmsg("\"%s\" is not a view",
16661651
RelationGetRelationName(targetrelation))));
16671652

1668-
relhastriggers = (targetrelation->rd_rel->reltriggers > 0);
1653+
/*
1654+
* Don't allow ALTER TABLE on composite types.
1655+
* We want people to use ALTER TYPE for that.
1656+
*/
1657+
if (relkind == RELKIND_COMPOSITE_TYPE)
1658+
ereport(ERROR,
1659+
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
1660+
errmsg("\"%s\" is a composite type",
1661+
RelationGetRelationName(targetrelation)),
1662+
errhint("Use ALTER TYPE instead.")));
1663+
1664+
/* Do the work */
1665+
RenameRelationInternal(myrelid, newrelname, namespaceId);
1666+
1667+
/*
1668+
* Close rel, but keep exclusive lock!
1669+
*/
1670+
relation_close(targetrelation, NoLock);
1671+
}
1672+
1673+
/*
1674+
* RenameRelationInternal - change the name of a relation
1675+
*
1676+
* XXX - When renaming sequences, we don't bother to modify the
1677+
* sequence name that is stored within the sequence itself
1678+
* (this would cause problems with MVCC). In the future,
1679+
* the sequence name should probably be removed from the
1680+
* sequence, AFAIK there's no need for it to be there.
1681+
*/
1682+
void
1683+
RenameRelationInternal(Oid myrelid, const char *newrelname, Oid namespaceId)
1684+
{
1685+
Relation targetrelation;
1686+
Relation relrelation; /* for RELATION relation */
1687+
HeapTuple reltup;
1688+
Form_pg_class relform;
1689+
1690+
/*
1691+
* Grab an exclusive lock on the target table, index, sequence or
1692+
* view, which we will NOT release until end of transaction.
1693+
*/
1694+
targetrelation = relation_open(myrelid, AccessExclusiveLock);
16691695

16701696
/*
16711697
* 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)
17031729
* Also rename the associated type, if any.
17041730
*/
17051731
if (OidIsValid(targetrelation->rd_rel->reltype))
1706-
TypeRename(targetrelation->rd_rel->reltype, newrelname, namespaceId);
1732+
RenameTypeInternal(targetrelation->rd_rel->reltype,
1733+
newrelname, namespaceId);
17071734

17081735
/*
17091736
* Also rename the associated constraint, if any.
17101737
*/
1711-
if (relkind == RELKIND_INDEX)
1738+
if (targetrelation->rd_rel->relkind == RELKIND_INDEX)
17121739
{
17131740
Oid constraintId = get_index_constraint(myrelid);
17141741

src/backend/commands/typecmds.c

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.113 2008/01/01 19:45:49 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.114 2008/03/19 18:38:30 tgl Exp $
1212
*
1313
* DESCRIPTION
1414
* The "DefineFoo" routines take the parse tree and pick out the
@@ -2339,6 +2339,76 @@ GetDomainConstraints(Oid typeOid)
23392339
return result;
23402340
}
23412341

2342+
2343+
/*
2344+
* Execute ALTER TYPE RENAME
2345+
*/
2346+
void
2347+
RenameType(List *names, const char *newTypeName)
2348+
{
2349+
TypeName *typename;
2350+
Oid typeOid;
2351+
Relation rel;
2352+
HeapTuple tup;
2353+
Form_pg_type typTup;
2354+
2355+
/* Make a TypeName so we can use standard type lookup machinery */
2356+
typename = makeTypeNameFromNameList(names);
2357+
typeOid = typenameTypeId(NULL, typename, NULL);
2358+
2359+
/* Look up the type in the type table */
2360+
rel = heap_open(TypeRelationId, RowExclusiveLock);
2361+
2362+
tup = SearchSysCacheCopy(TYPEOID,
2363+
ObjectIdGetDatum(typeOid),
2364+
0, 0, 0);
2365+
if (!HeapTupleIsValid(tup))
2366+
elog(ERROR, "cache lookup failed for type %u", typeOid);
2367+
typTup = (Form_pg_type) GETSTRUCT(tup);
2368+
2369+
/* check permissions on type */
2370+
if (!pg_type_ownercheck(typeOid, GetUserId()))
2371+
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE,
2372+
format_type_be(typeOid));
2373+
2374+
/*
2375+
* If it's a composite type, we need to check that it really is a
2376+
* free-standing composite type, and not a table's rowtype. We
2377+
* want people to use ALTER TABLE not ALTER TYPE for that case.
2378+
*/
2379+
if (typTup->typtype == TYPTYPE_COMPOSITE &&
2380+
get_rel_relkind(typTup->typrelid) != RELKIND_COMPOSITE_TYPE)
2381+
ereport(ERROR,
2382+
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
2383+
errmsg("%s is a table's row type",
2384+
format_type_be(typeOid)),
2385+
errhint("Use ALTER TABLE instead.")));
2386+
2387+
/* don't allow direct alteration of array types, either */
2388+
if (OidIsValid(typTup->typelem) &&
2389+
get_array_type(typTup->typelem) == typeOid)
2390+
ereport(ERROR,
2391+
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
2392+
errmsg("cannot alter array type %s",
2393+
format_type_be(typeOid)),
2394+
errhint("You can alter type %s, which will alter the array type as well.",
2395+
format_type_be(typTup->typelem))));
2396+
2397+
/*
2398+
* If type is composite we need to rename associated pg_class entry too.
2399+
* RenameRelationInternal will call RenameTypeInternal automatically.
2400+
*/
2401+
if (typTup->typtype == TYPTYPE_COMPOSITE)
2402+
RenameRelationInternal(typTup->typrelid, newTypeName,
2403+
typTup->typnamespace);
2404+
else
2405+
RenameTypeInternal(typeOid, newTypeName,
2406+
typTup->typnamespace);
2407+
2408+
/* Clean up */
2409+
heap_close(rel, RowExclusiveLock);
2410+
}
2411+
23422412
/*
23432413
* Change the owner of a type.
23442414
*/

src/backend/parser/gram.y

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.607 2008/02/15 22:17:06 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.608 2008/03/19 18:38:30 tgl Exp $
1515
*
1616
* HISTORY
1717
* AUTHOR DATE MAJOR EVENT
@@ -4734,6 +4734,14 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
47344734
n->newname = $8;
47354735
$$ = (Node *)n;
47364736
}
4737+
| ALTER TYPE_P any_name RENAME TO name
4738+
{
4739+
RenameStmt *n = makeNode(RenameStmt);
4740+
n->renameType = OBJECT_TYPE;
4741+
n->object = $3;
4742+
n->newname = $6;
4743+
$$ = (Node *)n;
4744+
}
47374745
;
47384746

47394747
opt_column: COLUMN { $$ = COLUMN; }

src/backend/tcop/utility.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.290 2008/03/14 17:25:58 alvherre Exp $
13+
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.291 2008/03/19 18:38:30 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -1613,6 +1613,9 @@ CreateCommandTag(Node *parsetree)
16131613
case OBJECT_TSCONFIGURATION:
16141614
tag = "ALTER TEXT SEARCH CONFIGURATION";
16151615
break;
1616+
case OBJECT_TYPE:
1617+
tag = "ALTER TYPE";
1618+
break;
16161619
default:
16171620
tag = "???";
16181621
break;

0 commit comments

Comments
 (0)