Fix incorrect code in new REINDEX CONCURRENTLY code

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.
This commit is contained in:
Peter Eisentraut 2019-03-29 10:53:40 +01:00
parent 5dc92b844e
commit bb76134b08
1 changed files with 16 additions and 12 deletions

View File

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