Fix relcache reference leak in refresh_by_match_merge().
One path through the loop over indexes forgot to do index_close(). Rather than adding a fourth call, restructure slightly so that there's only one. In passing, get rid of an unnecessary syscache lookup: the pg_index struct for the index is already available from its relcache entry. Per report from YAMAMOTO Takashi, though this is a bit different from his suggested patch. This is new code in HEAD, so no need for back-patch.
This commit is contained in:
parent
3bd261ca18
commit
f7271c4427
@ -609,40 +609,23 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid)
|
|||||||
{
|
{
|
||||||
Oid indexoid = lfirst_oid(indexoidscan);
|
Oid indexoid = lfirst_oid(indexoidscan);
|
||||||
Relation indexRel;
|
Relation indexRel;
|
||||||
HeapTuple indexTuple;
|
|
||||||
Form_pg_index indexStruct;
|
Form_pg_index indexStruct;
|
||||||
|
|
||||||
indexRel = index_open(indexoid, RowExclusiveLock);
|
indexRel = index_open(indexoid, RowExclusiveLock);
|
||||||
indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexoid));
|
indexStruct = indexRel->rd_index;
|
||||||
if (!HeapTupleIsValid(indexTuple)) /* should not happen */
|
|
||||||
elog(ERROR, "cache lookup failed for index %u", indexoid);
|
|
||||||
indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
|
|
||||||
|
|
||||||
/* We're only interested if it is unique and valid. */
|
/*
|
||||||
if (indexStruct->indisunique && IndexIsValid(indexStruct))
|
* We're only interested if it is unique, valid, contains no
|
||||||
|
* expressions, and is not partial.
|
||||||
|
*/
|
||||||
|
if (indexStruct->indisunique &&
|
||||||
|
IndexIsValid(indexStruct) &&
|
||||||
|
RelationGetIndexExpressions(indexRel) == NIL &&
|
||||||
|
RelationGetIndexPredicate(indexRel) == NIL)
|
||||||
{
|
{
|
||||||
int numatts = indexStruct->indnatts;
|
int numatts = indexStruct->indnatts;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Skip any index on an expression. */
|
|
||||||
if (RelationGetIndexExpressions(indexRel) != NIL)
|
|
||||||
{
|
|
||||||
index_close(indexRel, NoLock);
|
|
||||||
ReleaseSysCache(indexTuple);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip partial indexes. */
|
|
||||||
if (RelationGetIndexPredicate(indexRel) != NIL)
|
|
||||||
{
|
|
||||||
index_close(indexRel, NoLock);
|
|
||||||
ReleaseSysCache(indexTuple);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hold the locks, since we're about to run DML which needs them. */
|
|
||||||
index_close(indexRel, NoLock);
|
|
||||||
|
|
||||||
/* Add quals for all columns from this index. */
|
/* Add quals for all columns from this index. */
|
||||||
for (i = 0; i < numatts; i++)
|
for (i = 0; i < numatts; i++)
|
||||||
{
|
{
|
||||||
@ -675,7 +658,9 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid)
|
|||||||
foundUniqueIndex = true;
|
foundUniqueIndex = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ReleaseSysCache(indexTuple);
|
|
||||||
|
/* Keep the locks, since we're about to run DML which needs them. */
|
||||||
|
index_close(indexRel, NoLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
list_free(indexoidlist);
|
list_free(indexoidlist);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user