aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-09-23 23:20:24 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-09-23 23:20:24 +0000
commit688f0c56dcaf45a09fe21f236346ea7b84dac436 (patch)
treec25f4af9853e09f0194d31ce9960867b3f423e94 /src
parentfb147dc30e7ee931d9d105797f5210106d9ce55e (diff)
downloadpostgresql-688f0c56dcaf45a09fe21f236346ea7b84dac436.tar.gz
postgresql-688f0c56dcaf45a09fe21f236346ea7b84dac436.zip
Fix ALTER TABLE OWNER to adjust the ownership of dependent sequences,
not only indexes. Alvaro Herrera, with some kibitzing by Tom Lane.
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/tablecmds.c84
1 files changed, 79 insertions, 5 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 63ee33dd304..c8efaa23b1a 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
*
*
* 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 ATPostAlterTypeParse(char *cmd, List **wqueue);
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 ATExecDropCluster(Relation rel);
static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
@@ -5121,8 +5123,10 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
HeapTuple tuple;
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);
/* 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
- * any indexes that belong to the table, as well as the table's
- * toast table (if it has one)
+ * any indexes and sequences that belong to the table, as well as
+ * the table's toast table (if it has one)
*/
if (tuple_class->relkind == RELKIND_RELATION ||
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 (tuple_class->reltoastrelid != InvalidOid)
ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerSysId);
+
+ /* If it has dependent sequences, recurse to change them too */
+ change_owner_recurse_to_sequences(relationOid, newOwnerSysId);
}
}
@@ -5235,6 +5242,73 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
}
/*
+ * 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
*
* The only thing we have to do is to change the indisclustered bits.