8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -237,6 +237,8 @@ static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
237
237
static void ATPostAlterTypeCleanup (List * * wqueue , AlteredTableInfo * tab );
238
238
static void ATPostAlterTypeParse (char * cmd , List * * wqueue );
239
239
static void ATExecChangeOwner (Oid relationOid , int32 newOwnerSysId );
240
+ static void change_owner_recurse_to_sequences (Oid relationOid ,
241
+ int32 newOwnerSysId );
240
242
static void ATExecClusterOn (Relation rel , const char * indexName );
241
243
static void ATExecDropCluster (Relation rel );
242
244
static void ATPrepSetTableSpace (AlteredTableInfo * tab , Relation rel ,
@@ -5121,8 +5123,10 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
5121
5123
HeapTuple tuple ;
5122
5124
Form_pg_class tuple_class ;
5123
5125
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
+ */
5126
5130
target_rel = relation_open (relationOid , AccessExclusiveLock );
5127
5131
5128
5132
/* Get its pg_class tuple, too */
@@ -5202,8 +5206,8 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
5202
5206
5203
5207
/*
5204
5208
* 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)
5207
5211
*/
5208
5212
if (tuple_class -> relkind == RELKIND_RELATION ||
5209
5213
tuple_class -> relkind == RELKIND_TOASTVALUE )
@@ -5226,6 +5230,9 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
5226
5230
/* If it has a toast table, recurse to change its ownership */
5227
5231
if (tuple_class -> reltoastrelid != InvalidOid )
5228
5232
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 );
5229
5236
}
5230
5237
}
5231
5238
@@ -5234,6 +5241,73 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
5234
5241
relation_close (target_rel , NoLock );
5235
5242
}
5236
5243
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
+
5237
5311
/*
5238
5312
* ALTER TABLE CLUSTER ON
5239
5313
*
0 commit comments