diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 63ee33dd3045a3103680872d4a550a6c54a88e03..c8efaa23b1ad28f9f91f16df102f04eaf9567c84 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);
 		}
 	}
 
@@ -5234,6 +5241,73 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
 	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
  *