8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.159 2002/03/06 06:09:29 momjian Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.160 2002/03/06 19:58:26 momjian Exp $
12
12
*
13
13
* NOTES
14
14
* The PerformAddAttribute() code, like most of the relation
53
53
#include "utils/relcache.h"
54
54
#include "utils/temprel.h"
55
55
56
-
57
56
static void drop_default (Oid relid , int16 attnum );
58
57
static bool needs_toast_table (Relation rel );
59
-
58
+ static void AlterTableOwnerId (Oid relationOid , int32 newOwnerSysId );
59
+ static void CheckTupleType (Form_pg_class tuple_class );
60
60
61
61
/* --------------------------------
62
62
* PortalCleanup
@@ -1559,59 +1559,58 @@ AlterTableDropConstraint(const char *relationName,
1559
1559
elog (NOTICE , "Multiple constraints dropped" );
1560
1560
}
1561
1561
1562
-
1563
1562
/*
1564
1563
* ALTER TABLE OWNER
1565
1564
*/
1566
1565
void
1567
1566
AlterTableOwner (const char * relationName , const char * newOwnerName )
1568
1567
{
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 ;
1573
1571
1574
- /*
1575
- * first check that we are a superuser
1576
- */
1572
+ /* check that we are the superuser */
1577
1573
if (!superuser ())
1578
1574
elog (ERROR , "ALTER TABLE: permission denied" );
1579
1575
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 );
1584
1580
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
+ }
1589
1587
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 ),
1592
1598
0 , 0 , 0 );
1593
1599
if (!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 );
1596
1602
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 );
1609
1607
1610
1608
/*
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.
1612
1611
*/
1613
- (( Form_pg_class ) GETSTRUCT ( tuple )) -> relowner = newOwnerSysid ;
1614
-
1612
+ class_rel = heap_openr ( RelationRelationName , RowExclusiveLock ) ;
1613
+ tuple_class -> relowner = newOwnerSysId ;
1615
1614
simple_heap_update (class_rel , & tuple -> t_self , tuple );
1616
1615
1617
1616
/* Keep the catalog indices up to date */
@@ -1620,12 +1619,48 @@ AlterTableOwner(const char *relationName, const char *newOwnerName)
1620
1619
CatalogCloseIndices (Num_pg_class_indices , idescs );
1621
1620
1622
1621
/*
1623
- * unlock everything and return
1622
+ * If we are operating on a table, also change the ownership
1623
+ * of all of its indexes.
1624
1624
*/
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
+
1625
1644
heap_freetuple (tuple );
1626
1645
heap_close (class_rel , NoLock );
1627
1646
}
1628
1647
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
+ }
1629
1664
1630
1665
/*
1631
1666
* ALTER TABLE CREATE TOAST TABLE
0 commit comments