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 */
16241621void
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
0 commit comments