mirror of
https://github.com/postgres/postgres.git
synced 2025-04-24 10:47:04 +03:00
Fix ALTER TABLE OWNER to adjust the ownership of dependent sequences,
not only indexes. Alvaro Herrera, with some kibitzing by Tom Lane.
This commit is contained in:
parent
fb147dc30e
commit
688f0c56dc
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.132 2004/09/16 16:58:28 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.133 2004/09/23 23:20:24 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -237,6 +237,8 @@ static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
|
|||||||
static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab);
|
static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab);
|
||||||
static void ATPostAlterTypeParse(char *cmd, List **wqueue);
|
static void ATPostAlterTypeParse(char *cmd, List **wqueue);
|
||||||
static void ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId);
|
static void ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId);
|
||||||
|
static void change_owner_recurse_to_sequences(Oid relationOid,
|
||||||
|
int32 newOwnerSysId);
|
||||||
static void ATExecClusterOn(Relation rel, const char *indexName);
|
static void ATExecClusterOn(Relation rel, const char *indexName);
|
||||||
static void ATExecDropCluster(Relation rel);
|
static void ATExecDropCluster(Relation rel);
|
||||||
static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
|
static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
|
||||||
@ -5121,8 +5123,10 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
|
|||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Form_pg_class tuple_class;
|
Form_pg_class tuple_class;
|
||||||
|
|
||||||
/* Get exclusive lock till end of transaction on the target table */
|
/*
|
||||||
/* Use relation_open here so that we work on indexes... */
|
* Get exclusive lock till end of transaction on the target table.
|
||||||
|
* Use relation_open so that we can work on indexes and sequences.
|
||||||
|
*/
|
||||||
target_rel = relation_open(relationOid, AccessExclusiveLock);
|
target_rel = relation_open(relationOid, AccessExclusiveLock);
|
||||||
|
|
||||||
/* Get its pg_class tuple, too */
|
/* Get its pg_class tuple, too */
|
||||||
@ -5202,8 +5206,8 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are operating on a table, also change the ownership of
|
* If we are operating on a table, also change the ownership of
|
||||||
* any indexes that belong to the table, as well as the table's
|
* any indexes and sequences that belong to the table, as well as
|
||||||
* toast table (if it has one)
|
* the table's toast table (if it has one)
|
||||||
*/
|
*/
|
||||||
if (tuple_class->relkind == RELKIND_RELATION ||
|
if (tuple_class->relkind == RELKIND_RELATION ||
|
||||||
tuple_class->relkind == RELKIND_TOASTVALUE)
|
tuple_class->relkind == RELKIND_TOASTVALUE)
|
||||||
@ -5226,6 +5230,9 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
|
|||||||
/* If it has a toast table, recurse to change its ownership */
|
/* If it has a toast table, recurse to change its ownership */
|
||||||
if (tuple_class->reltoastrelid != InvalidOid)
|
if (tuple_class->reltoastrelid != InvalidOid)
|
||||||
ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerSysId);
|
ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerSysId);
|
||||||
|
|
||||||
|
/* If it has dependent sequences, recurse to change them too */
|
||||||
|
change_owner_recurse_to_sequences(relationOid, newOwnerSysId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5234,6 +5241,73 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
|
|||||||
relation_close(target_rel, NoLock);
|
relation_close(target_rel, NoLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* change_owner_recurse_to_sequences
|
||||||
|
*
|
||||||
|
* Helper function for ATExecChangeOwner. Examines pg_depend searching
|
||||||
|
* for sequences that are dependent on serial columns, and changes their
|
||||||
|
* ownership.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
change_owner_recurse_to_sequences(Oid relationOid, int32 newOwnerSysId)
|
||||||
|
{
|
||||||
|
Relation depRel;
|
||||||
|
SysScanDesc scan;
|
||||||
|
ScanKeyData key[2];
|
||||||
|
HeapTuple tup;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SERIAL sequences are those having an internal dependency on one
|
||||||
|
* of the table's columns (we don't care *which* column, exactly).
|
||||||
|
*/
|
||||||
|
depRel = heap_openr(DependRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
|
ScanKeyInit(&key[0],
|
||||||
|
Anum_pg_depend_refclassid,
|
||||||
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(RelOid_pg_class));
|
||||||
|
ScanKeyInit(&key[1],
|
||||||
|
Anum_pg_depend_refobjid,
|
||||||
|
BTEqualStrategyNumber, F_OIDEQ,
|
||||||
|
ObjectIdGetDatum(relationOid));
|
||||||
|
/* we leave refobjsubid unspecified */
|
||||||
|
|
||||||
|
scan = systable_beginscan(depRel, DependReferenceIndex, true,
|
||||||
|
SnapshotNow, 2, key);
|
||||||
|
|
||||||
|
while (HeapTupleIsValid(tup = systable_getnext(scan)))
|
||||||
|
{
|
||||||
|
Form_pg_depend depForm = (Form_pg_depend) GETSTRUCT(tup);
|
||||||
|
Relation seqRel;
|
||||||
|
|
||||||
|
/* skip dependencies other than internal dependencies on columns */
|
||||||
|
if (depForm->refobjsubid == 0 ||
|
||||||
|
depForm->classid != RelOid_pg_class ||
|
||||||
|
depForm->objsubid != 0 ||
|
||||||
|
depForm->deptype != DEPENDENCY_INTERNAL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Use relation_open just in case it's an index */
|
||||||
|
seqRel = relation_open(depForm->objid, AccessExclusiveLock);
|
||||||
|
|
||||||
|
/* skip non-sequence relations */
|
||||||
|
if (RelationGetForm(seqRel)->relkind != RELKIND_SEQUENCE)
|
||||||
|
{
|
||||||
|
/* No need to keep the lock */
|
||||||
|
relation_close(seqRel, AccessExclusiveLock);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We don't need to close the sequence while we alter it. */
|
||||||
|
ATExecChangeOwner(depForm->objid, newOwnerSysId);
|
||||||
|
|
||||||
|
/* Now we can close it. Keep the lock till end of transaction. */
|
||||||
|
relation_close(seqRel, NoLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
systable_endscan(scan);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ALTER TABLE CLUSTER ON
|
* ALTER TABLE CLUSTER ON
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user