Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 688f0c5

Browse files
committed
Fix ALTER TABLE OWNER to adjust the ownership of dependent sequences,
not only indexes. Alvaro Herrera, with some kibitzing by Tom Lane.
1 parent fb147dc commit 688f0c5

File tree

1 file changed

+79
-5
lines changed

1 file changed

+79
-5
lines changed

src/backend/commands/tablecmds.c

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.132 2004/09/16 16:58:28 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.133 2004/09/23 23:20:24 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -237,6 +237,8 @@ static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
237237
static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab);
238238
static void ATPostAlterTypeParse(char *cmd, List **wqueue);
239239
static void ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId);
240+
static void change_owner_recurse_to_sequences(Oid relationOid,
241+
int32 newOwnerSysId);
240242
static void ATExecClusterOn(Relation rel, const char *indexName);
241243
static void ATExecDropCluster(Relation rel);
242244
static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
@@ -5121,8 +5123,10 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
51215123
HeapTuple tuple;
51225124
Form_pg_class tuple_class;
51235125

5124-
/* Get exclusive lock till end of transaction on the target table */
5125-
/* Use relation_open here so that we work on indexes... */
5126+
/*
5127+
* Get exclusive lock till end of transaction on the target table.
5128+
* Use relation_open so that we can work on indexes and sequences.
5129+
*/
51265130
target_rel = relation_open(relationOid, AccessExclusiveLock);
51275131

51285132
/* Get its pg_class tuple, too */
@@ -5202,8 +5206,8 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
52025206

52035207
/*
52045208
* If we are operating on a table, also change the ownership of
5205-
* any indexes that belong to the table, as well as the table's
5206-
* toast table (if it has one)
5209+
* any indexes and sequences that belong to the table, as well as
5210+
* the table's toast table (if it has one)
52075211
*/
52085212
if (tuple_class->relkind == RELKIND_RELATION ||
52095213
tuple_class->relkind == RELKIND_TOASTVALUE)
@@ -5226,6 +5230,9 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
52265230
/* If it has a toast table, recurse to change its ownership */
52275231
if (tuple_class->reltoastrelid != InvalidOid)
52285232
ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerSysId);
5233+
5234+
/* If it has dependent sequences, recurse to change them too */
5235+
change_owner_recurse_to_sequences(relationOid, newOwnerSysId);
52295236
}
52305237
}
52315238

@@ -5234,6 +5241,73 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
52345241
relation_close(target_rel, NoLock);
52355242
}
52365243

5244+
/*
5245+
* change_owner_recurse_to_sequences
5246+
*
5247+
* Helper function for ATExecChangeOwner. Examines pg_depend searching
5248+
* for sequences that are dependent on serial columns, and changes their
5249+
* ownership.
5250+
*/
5251+
static void
5252+
change_owner_recurse_to_sequences(Oid relationOid, int32 newOwnerSysId)
5253+
{
5254+
Relation depRel;
5255+
SysScanDesc scan;
5256+
ScanKeyData key[2];
5257+
HeapTuple tup;
5258+
5259+
/*
5260+
* SERIAL sequences are those having an internal dependency on one
5261+
* of the table's columns (we don't care *which* column, exactly).
5262+
*/
5263+
depRel = heap_openr(DependRelationName, RowExclusiveLock);
5264+
5265+
ScanKeyInit(&key[0],
5266+
Anum_pg_depend_refclassid,
5267+
BTEqualStrategyNumber, F_OIDEQ,
5268+
ObjectIdGetDatum(RelOid_pg_class));
5269+
ScanKeyInit(&key[1],
5270+
Anum_pg_depend_refobjid,
5271+
BTEqualStrategyNumber, F_OIDEQ,
5272+
ObjectIdGetDatum(relationOid));
5273+
/* we leave refobjsubid unspecified */
5274+
5275+
scan = systable_beginscan(depRel, DependReferenceIndex, true,
5276+
SnapshotNow, 2, key);
5277+
5278+
while (HeapTupleIsValid(tup = systable_getnext(scan)))
5279+
{
5280+
Form_pg_depend depForm = (Form_pg_depend) GETSTRUCT(tup);
5281+
Relation seqRel;
5282+
5283+
/* skip dependencies other than internal dependencies on columns */
5284+
if (depForm->refobjsubid == 0 ||
5285+
depForm->classid != RelOid_pg_class ||
5286+
depForm->objsubid != 0 ||
5287+
depForm->deptype != DEPENDENCY_INTERNAL)
5288+
continue;
5289+
5290+
/* Use relation_open just in case it's an index */
5291+
seqRel = relation_open(depForm->objid, AccessExclusiveLock);
5292+
5293+
/* skip non-sequence relations */
5294+
if (RelationGetForm(seqRel)->relkind != RELKIND_SEQUENCE)
5295+
{
5296+
/* No need to keep the lock */
5297+
relation_close(seqRel, AccessExclusiveLock);
5298+
continue;
5299+
}
5300+
5301+
/* We don't need to close the sequence while we alter it. */
5302+
ATExecChangeOwner(depForm->objid, newOwnerSysId);
5303+
5304+
/* Now we can close it. Keep the lock till end of transaction. */
5305+
relation_close(seqRel, NoLock);
5306+
}
5307+
5308+
systable_endscan(scan);
5309+
}
5310+
52375311
/*
52385312
* ALTER TABLE CLUSTER ON
52395313
*

0 commit comments

Comments
 (0)