@@ -91,6 +91,15 @@ static bool ReindexRelationConcurrently(Oid relationOid, int options);
91
91
static void ReindexPartitionedIndex (Relation parentIdx );
92
92
static void update_relispartition (Oid relationId , bool newval );
93
93
94
+ /*
95
+ * callback argument type for RangeVarCallbackForReindexIndex()
96
+ */
97
+ struct ReindexIndexCallbackState
98
+ {
99
+ bool concurrent ; /* flag from statement */
100
+ Oid locked_table_oid ; /* tracks previously locked table */
101
+ };
102
+
94
103
/*
95
104
* CheckIndexCompatible
96
105
* Determine whether an existing index definition is compatible with a
@@ -2303,8 +2312,8 @@ ChooseIndexColumnNames(List *indexElems)
2303
2312
void
2304
2313
ReindexIndex (RangeVar * indexRelation , int options , bool concurrent )
2305
2314
{
2315
+ struct ReindexIndexCallbackState state ;
2306
2316
Oid indOid ;
2307
- Oid heapOid = InvalidOid ;
2308
2317
Relation irel ;
2309
2318
char persistence ;
2310
2319
@@ -2313,11 +2322,13 @@ ReindexIndex(RangeVar *indexRelation, int options, bool concurrent)
2313
2322
* obtain lock on table first, to avoid deadlock hazard. The lock level
2314
2323
* used here must match the index lock obtained in reindex_index().
2315
2324
*/
2325
+ state .concurrent = concurrent ;
2326
+ state .locked_table_oid = InvalidOid ;
2316
2327
indOid = RangeVarGetRelidExtended (indexRelation ,
2317
2328
concurrent ? ShareUpdateExclusiveLock : AccessExclusiveLock ,
2318
2329
0 ,
2319
2330
RangeVarCallbackForReindexIndex ,
2320
- ( void * ) & heapOid );
2331
+ & state );
2321
2332
2322
2333
/*
2323
2334
* Obtain the current persistence of the existing index. We already hold
@@ -2350,7 +2361,15 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
2350
2361
Oid relId , Oid oldRelId , void * arg )
2351
2362
{
2352
2363
char relkind ;
2353
- Oid * heapOid = (Oid * ) arg ;
2364
+ struct ReindexIndexCallbackState * state = arg ;
2365
+ LOCKMODE table_lockmode ;
2366
+
2367
+ /*
2368
+ * Lock level here should match table lock in reindex_index() for
2369
+ * non-concurrent case and table locks used by index_concurrently_*() for
2370
+ * concurrent case.
2371
+ */
2372
+ table_lockmode = state -> concurrent ? ShareUpdateExclusiveLock : ShareLock ;
2354
2373
2355
2374
/*
2356
2375
* If we previously locked some other index's heap, and the name we're
@@ -2359,9 +2378,8 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
2359
2378
*/
2360
2379
if (relId != oldRelId && OidIsValid (oldRelId ))
2361
2380
{
2362
- /* lock level here should match reindex_index() heap lock */
2363
- UnlockRelationOid (* heapOid , ShareLock );
2364
- * heapOid = InvalidOid ;
2381
+ UnlockRelationOid (state -> locked_table_oid , table_lockmode );
2382
+ state -> locked_table_oid = InvalidOid ;
2365
2383
}
2366
2384
2367
2385
/* If the relation does not exist, there's nothing more to do. */
@@ -2389,14 +2407,17 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
2389
2407
/* Lock heap before index to avoid deadlock. */
2390
2408
if (relId != oldRelId )
2391
2409
{
2410
+ Oid table_oid = IndexGetRelation (relId , true);
2411
+
2392
2412
/*
2393
- * Lock level here should match reindex_index() heap lock. If the OID
2394
- * isn't valid, it means the index as concurrently dropped, which is
2395
- * not a problem for us; just return normally.
2413
+ * If the OID isn't valid, it means the index was concurrently
2414
+ * dropped, which is not a problem for us; just return normally.
2396
2415
*/
2397
- * heapOid = IndexGetRelation (relId , true);
2398
- if (OidIsValid (* heapOid ))
2399
- LockRelationOid (* heapOid , ShareLock );
2416
+ if (OidIsValid (table_oid ))
2417
+ {
2418
+ LockRelationOid (table_oid , table_lockmode );
2419
+ state -> locked_table_oid = table_oid ;
2420
+ }
2400
2421
}
2401
2422
}
2402
2423
0 commit comments