From f7271c44278352516ec66b2de311952ce330b6d5 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 18 Mar 2014 11:36:45 -0400 Subject: [PATCH] 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. --- src/backend/commands/matview.c | 41 +++++++++++----------------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index d64f165706..a301d65b60 100644 --- a/src/backend/commands/matview.c +++ b/src/backend/commands/matview.c @@ -609,40 +609,23 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid) { Oid indexoid = lfirst_oid(indexoidscan); Relation indexRel; - HeapTuple indexTuple; Form_pg_index indexStruct; indexRel = index_open(indexoid, RowExclusiveLock); - indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexoid)); - 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)) + indexStruct = indexRel->rd_index; + + /* + * 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 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. */ for (i = 0; i < numatts; i++) { @@ -675,7 +658,9 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid) foundUniqueIndex = true; } } - ReleaseSysCache(indexTuple); + + /* Keep the locks, since we're about to run DML which needs them. */ + index_close(indexRel, NoLock); } list_free(indexoidlist); -- GitLab