88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.159 2002/03/0606:09:29 momjian Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.160 2002/03/0619:58:26 momjian Exp $
1212 *
1313 * NOTES
1414 * The PerformAddAttribute() code, like most of the relation
5353#include "utils/relcache.h"
5454#include "utils/temprel.h"
5555
56-
5756static void drop_default (Oid relid ,int16 attnum );
5857static bool needs_toast_table (Relation rel );
59-
58+ static void AlterTableOwnerId (Oid relationOid ,int32 newOwnerSysId );
59+ static void CheckTupleType (Form_pg_class tuple_class );
6060
6161/* --------------------------------
6262 *PortalCleanup
@@ -1559,59 +1559,58 @@ AlterTableDropConstraint(const char *relationName,
15591559elog (NOTICE ,"Multiple constraints dropped" );
15601560}
15611561
1562-
15631562/*
15641563 * ALTER TABLE OWNER
15651564 */
15661565void
15671566AlterTableOwner (const char * relationName ,const char * newOwnerName )
15681567{
1569- Relation class_rel ;
1570- HeapTuple tuple ;
1571- int32 newOwnerSysid ;
1572- Relation idescs [Num_pg_class_indices ];
1568+ Oid relationOid ;
1569+ Relation relation ;
1570+ int32 newOwnerSysId ;
15731571
1574- /*
1575- * first check that we are a superuser
1576- */
1572+ /* check that we are the superuser */
15771573if (!superuser ())
15781574elog (ERROR ,"ALTER TABLE: permission denied" );
15791575
1580- /*
1581- * look up the new owner in pg_shadow and get the sysid
1582- */
1583- newOwnerSysid = get_usesysid ( newOwnerName );
1576+ /* lookup the OID of the target relation */
1577+ relation = RelationNameGetRelation ( relationName );
1578+ relationOid = relation -> rd_id ;
1579+ RelationClose ( relation );
15841580
1585- /*
1586- * find the table's entry in pg_class and make a modifiable copy
1587- */
1588- class_rel = heap_openr (RelationRelationName ,RowExclusiveLock );
1581+ /* lookup the sysid of the new owner */
1582+ newOwnerSysId = get_usesysid (newOwnerName );
1583+
1584+ /* do all the actual work */
1585+ AlterTableOwnerId (relationOid ,newOwnerSysId );
1586+ }
15891587
1590- tuple = SearchSysCacheCopy (RELNAME ,
1591- PointerGetDatum (relationName ),
1588+ static void
1589+ AlterTableOwnerId (Oid relationOid ,int32 newOwnerSysId )
1590+ {
1591+ Relation class_rel ;
1592+ HeapTuple tuple ;
1593+ Relation idescs [Num_pg_class_indices ];
1594+ Form_pg_class tuple_class ;
1595+
1596+ tuple = SearchSysCacheCopy (RELOID ,
1597+ ObjectIdGetDatum (relationOid ),
159215980 ,0 ,0 );
15931599if (!HeapTupleIsValid (tuple ))
1594- elog (ERROR ,"ALTER TABLE:relation \"%s\" not found" ,
1595- relationName );
1600+ elog (ERROR ,"ALTER TABLE:object ID %hd not found" ,
1601+ relationOid );
15961602
1597- switch (((Form_pg_class )GETSTRUCT (tuple ))-> relkind )
1598- {
1599- case RELKIND_RELATION :
1600- case RELKIND_INDEX :
1601- case RELKIND_VIEW :
1602- case RELKIND_SEQUENCE :
1603- /* ok to change owner */
1604- break ;
1605- default :
1606- elog (ERROR ,"ALTER TABLE: relation \"%s\" is not a table, index, view, or sequence" ,
1607- relationName );
1608- }
1603+ tuple_class = (Form_pg_class )GETSTRUCT (tuple );
1604+
1605+ /* Can we change the ownership of this tuple? */
1606+ CheckTupleType (tuple_class );
16091607
16101608/*
1611- * modify the table's entry and write to the heap
1609+ * Okay, this is a valid tuple: change its ownership and
1610+ * write to the heap.
16121611 */
1613- (( Form_pg_class ) GETSTRUCT ( tuple )) -> relowner = newOwnerSysid ;
1614-
1612+ class_rel = heap_openr ( RelationRelationName , RowExclusiveLock ) ;
1613+ tuple_class -> relowner = newOwnerSysId ;
16151614simple_heap_update (class_rel ,& tuple -> t_self ,tuple );
16161615
16171616/* Keep the catalog indices up to date */
@@ -1620,12 +1619,48 @@ AlterTableOwner(const char *relationName, const char *newOwnerName)
16201619CatalogCloseIndices (Num_pg_class_indices ,idescs );
16211620
16221621/*
1623- * unlock everything and return
1622+ * If we are operating on a table, also change the ownership
1623+ * of all of its indexes.
16241624 */
1625+ if (tuple_class -> relkind == RELKIND_RELATION )
1626+ {
1627+ Relation target_rel ;
1628+ List * index_oid_list ,* i ;
1629+
1630+ /* Find all the indexes belonging to this relation */
1631+ target_rel = heap_open (relationOid ,RowExclusiveLock );
1632+ index_oid_list = RelationGetIndexList (target_rel );
1633+ heap_close (target_rel ,RowExclusiveLock );
1634+
1635+ /* For each index, recursively change its ownership */
1636+ foreach (i ,index_oid_list )
1637+ {
1638+ AlterTableOwnerId (lfirsti (i ),newOwnerSysId );
1639+ }
1640+
1641+ freeList (index_oid_list );
1642+ }
1643+
16251644heap_freetuple (tuple );
16261645heap_close (class_rel ,NoLock );
16271646}
16281647
1648+ static void
1649+ CheckTupleType (Form_pg_class tuple_class )
1650+ {
1651+ switch (tuple_class -> relkind )
1652+ {
1653+ case RELKIND_RELATION :
1654+ case RELKIND_INDEX :
1655+ case RELKIND_VIEW :
1656+ case RELKIND_SEQUENCE :
1657+ /* ok to change owner */
1658+ break ;
1659+ default :
1660+ elog (ERROR ,"ALTER TABLE: relation \"%s\" is not a table, index, view, or sequence" ,
1661+ NameStr (tuple_class -> relname ));
1662+ }
1663+ }
16291664
16301665/*
16311666 * ALTER TABLE CREATE TOAST TABLE