@ -345,6 +345,8 @@ static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
AlterTableCmd * cmd , LOCKMODE lockmode ) ;
static void ATPostAlterTypeCleanup ( List * * wqueue , AlteredTableInfo * tab , LOCKMODE lockmode ) ;
static void ATPostAlterTypeParse ( char * cmd , List * * wqueue , LOCKMODE lockmode ) ;
static void change_owner_fix_column_acls ( Oid relationOid ,
Oid oldOwnerId , Oid newOwnerId ) ;
static void change_owner_recurse_to_sequences ( Oid relationOid ,
Oid newOwnerId , LOCKMODE lockmode ) ;
static void ATExecClusterOn ( Relation rel , const char * indexName , LOCKMODE lockmode ) ;
@ -7530,6 +7532,14 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lock
heap_freetuple ( newtuple ) ;
/*
* We must similarly update any per - column ACLs to reflect the new
* owner ; for neatness reasons that ' s split out as a subroutine .
*/
change_owner_fix_column_acls ( relationOid ,
tuple_class - > relowner ,
newOwnerId ) ;
/*
* Update owner dependency reference , if any . A composite type has
* none , because it ' s tracked for the pg_type entry instead of here ;
@ -7586,6 +7596,71 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lock
relation_close ( target_rel , NoLock ) ;
}
/*
* change_owner_fix_column_acls
*
* Helper function for ATExecChangeOwner . Scan the columns of the table
* and fix any non - null column ACLs to reflect the new owner .
*/
static void
change_owner_fix_column_acls ( Oid relationOid , Oid oldOwnerId , Oid newOwnerId )
{
Relation attRelation ;
SysScanDesc scan ;
ScanKeyData key [ 1 ] ;
HeapTuple attributeTuple ;
attRelation = heap_open ( AttributeRelationId , RowExclusiveLock ) ;
ScanKeyInit ( & key [ 0 ] ,
Anum_pg_attribute_attrelid ,
BTEqualStrategyNumber , F_OIDEQ ,
ObjectIdGetDatum ( relationOid ) ) ;
scan = systable_beginscan ( attRelation , AttributeRelidNumIndexId ,
true , SnapshotNow , 1 , key ) ;
while ( HeapTupleIsValid ( attributeTuple = systable_getnext ( scan ) ) )
{
Form_pg_attribute att = ( Form_pg_attribute ) GETSTRUCT ( attributeTuple ) ;
Datum repl_val [ Natts_pg_attribute ] ;
bool repl_null [ Natts_pg_attribute ] ;
bool repl_repl [ Natts_pg_attribute ] ;
Acl * newAcl ;
Datum aclDatum ;
bool isNull ;
HeapTuple newtuple ;
/* Ignore dropped columns */
if ( att - > attisdropped )
continue ;
aclDatum = heap_getattr ( attributeTuple ,
Anum_pg_attribute_attacl ,
RelationGetDescr ( attRelation ) ,
& isNull ) ;
/* Null ACLs do not require changes */
if ( isNull )
continue ;
memset ( repl_null , false , sizeof ( repl_null ) ) ;
memset ( repl_repl , false , sizeof ( repl_repl ) ) ;
newAcl = aclnewowner ( DatumGetAclP ( aclDatum ) ,
oldOwnerId , newOwnerId ) ;
repl_repl [ Anum_pg_attribute_attacl - 1 ] = true ;
repl_val [ Anum_pg_attribute_attacl - 1 ] = PointerGetDatum ( newAcl ) ;
newtuple = heap_modify_tuple ( attributeTuple ,
RelationGetDescr ( attRelation ) ,
repl_val , repl_null , repl_repl ) ;
simple_heap_update ( attRelation , & newtuple - > t_self , newtuple ) ;
CatalogUpdateIndexes ( attRelation , newtuple ) ;
heap_freetuple ( newtuple ) ;
}
systable_endscan ( scan ) ;
heap_close ( attRelation , RowExclusiveLock ) ;
}
/*
* change_owner_recurse_to_sequences
*