@@ -91,6 +91,15 @@ static bool ReindexRelationConcurrently(Oid relationOid, int options);
9191static void ReindexPartitionedIndex (Relation parentIdx );
9292static void update_relispartition (Oid relationId ,bool newval );
9393
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+
94103/*
95104 * CheckIndexCompatible
96105 *Determine whether an existing index definition is compatible with a
@@ -2303,8 +2312,8 @@ ChooseIndexColumnNames(List *indexElems)
23032312void
23042313ReindexIndex (RangeVar * indexRelation ,int options ,bool concurrent )
23052314{
2315+ struct ReindexIndexCallbackState state ;
23062316Oid indOid ;
2307- Oid heapOid = InvalidOid ;
23082317Relation irel ;
23092318char persistence ;
23102319
@@ -2313,11 +2322,13 @@ ReindexIndex(RangeVar *indexRelation, int options, bool concurrent)
23132322 * obtain lock on table first, to avoid deadlock hazard. The lock level
23142323 * used here must match the index lock obtained in reindex_index().
23152324 */
2325+ state .concurrent = concurrent ;
2326+ state .locked_table_oid = InvalidOid ;
23162327indOid = RangeVarGetRelidExtended (indexRelation ,
23172328concurrent ?ShareUpdateExclusiveLock :AccessExclusiveLock ,
231823290 ,
23192330RangeVarCallbackForReindexIndex ,
2320- ( void * ) & heapOid );
2331+ & state );
23212332
23222333/*
23232334 * Obtain the current persistence of the existing index. We already hold
@@ -2350,7 +2361,15 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
23502361Oid relId ,Oid oldRelId ,void * arg )
23512362{
23522363char 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 ;
23542373
23552374/*
23562375 * If we previously locked some other index's heap, and the name we're
@@ -2359,9 +2378,8 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
23592378 */
23602379if (relId != oldRelId && OidIsValid (oldRelId ))
23612380{
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 ;
23652383}
23662384
23672385/* If the relation does not exist, there's nothing more to do. */
@@ -2389,14 +2407,17 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
23892407/* Lock heap before index to avoid deadlock. */
23902408if (relId != oldRelId )
23912409{
2410+ Oid table_oid = IndexGetRelation (relId , true);
2411+
23922412/*
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.
23962415 */
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+ }
24002421}
24012422}
24022423