Fix incorrect code in new REINDEX CONCURRENTLY code
authorPeter Eisentraut <peter@eisentraut.org>
Fri, 29 Mar 2019 09:53:40 +0000 (10:53 +0100)
committerPeter Eisentraut <peter@eisentraut.org>
Fri, 29 Mar 2019 09:53:40 +0000 (10:53 +0100)
The previous code was adding pointers to transient variables to a
list, but by the time the list was read, the variable might be gone,
depending on the compiler.  Fix it by making copies in the proper
memory context.

src/backend/commands/indexcmds.c

index c68d8d58167f159222c6870cd10118087044c100..ea07be69dbdf5fa15e7d4c215045d99c1cb0f67f 100644 (file)
@@ -2813,7 +2813,7 @@ ReindexRelationConcurrently(Oid relationOid, int options)
        Relation    indexRel;
        Relation    heapRel;
        Relation    newIndexRel;
-       LockRelId   lockrelid;
+       LockRelId  *lockrelid;
 
        indexRel = index_open(indexId, ShareUpdateExclusiveLock);
        heapRel = table_open(indexRel->rd_index->indrelid,
@@ -2847,10 +2847,12 @@ ReindexRelationConcurrently(Oid relationOid, int options)
         * avoid multiple locks taken on the same relation, instead we rely on
         * parentRelationIds built earlier.
         */
-       lockrelid = indexRel->rd_lockInfo.lockRelId;
-       relationLocks = lappend(relationLocks, &lockrelid);
-       lockrelid = newIndexRel->rd_lockInfo.lockRelId;
-       relationLocks = lappend(relationLocks, &lockrelid);
+       lockrelid = palloc(sizeof(*lockrelid));
+       *lockrelid = indexRel->rd_lockInfo.lockRelId;
+       relationLocks = lappend(relationLocks, lockrelid);
+       lockrelid = palloc(sizeof(*lockrelid));
+       *lockrelid = newIndexRel->rd_lockInfo.lockRelId;
+       relationLocks = lappend(relationLocks, lockrelid);
 
        MemoryContextSwitchTo(oldcontext);
 
@@ -2866,19 +2868,21 @@ ReindexRelationConcurrently(Oid relationOid, int options)
    foreach(lc, heapRelationIds)
    {
        Relation    heapRelation = table_open(lfirst_oid(lc), ShareUpdateExclusiveLock);
-       LockRelId   lockrelid = heapRelation->rd_lockInfo.lockRelId;
+       LockRelId  *lockrelid;
        LOCKTAG    *heaplocktag;
 
        /* Save the list of locks in private context */
        oldcontext = MemoryContextSwitchTo(private_context);
 
        /* Add lockrelid of heap relation to the list of locked relations */
-       relationLocks = lappend(relationLocks, &lockrelid);
+       lockrelid = palloc(sizeof(*lockrelid));
+       *lockrelid = heapRelation->rd_lockInfo.lockRelId;
+       relationLocks = lappend(relationLocks, lockrelid);
 
        heaplocktag = (LOCKTAG *) palloc(sizeof(LOCKTAG));
 
        /* Save the LOCKTAG for this parent relation for the wait phase */
-       SET_LOCKTAG_RELATION(*heaplocktag, lockrelid.dbId, lockrelid.relId);
+       SET_LOCKTAG_RELATION(*heaplocktag, lockrelid->dbId, lockrelid->relId);
        lockTags = lappend(lockTags, heaplocktag);
 
        MemoryContextSwitchTo(oldcontext);
@@ -2890,9 +2894,9 @@ ReindexRelationConcurrently(Oid relationOid, int options)
    /* Get a session-level lock on each table. */
    foreach(lc, relationLocks)
    {
-       LockRelId   lockRel = *((LockRelId *) lfirst(lc));
+       LockRelId   *lockrelid = (LockRelId *) lfirst(lc);
 
-       LockRelationIdForSession(&lockRel, ShareUpdateExclusiveLock);
+       LockRelationIdForSession(lockrelid, ShareUpdateExclusiveLock);
    }
 
    PopActiveSnapshot();
@@ -3127,9 +3131,9 @@ ReindexRelationConcurrently(Oid relationOid, int options)
     */
    foreach(lc, relationLocks)
    {
-       LockRelId   lockRel = *((LockRelId *) lfirst(lc));
+       LockRelId   *lockrelid = (LockRelId *) lfirst(lc);
 
-       UnlockRelationIdForSession(&lockRel, ShareUpdateExclusiveLock);
+       UnlockRelationIdForSession(lockrelid, ShareUpdateExclusiveLock);
    }
 
    /* Start a new transaction to finish process properly */