diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2014-03-18 11:36:45 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2014-03-18 11:36:53 -0400 |
commit | f7271c44278352516ec66b2de311952ce330b6d5 (patch) | |
tree | 780a328ed198459a8d1968a8a759472becfb4bf1 /src | |
parent | 3bd261ca18c67eafe18088e58fab511e3b965418 (diff) | |
download | postgresql-f7271c44278352516ec66b2de311952ce330b6d5.tar.gz postgresql-f7271c44278352516ec66b2de311952ce330b6d5.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/commands/matview.c | 41 |
1 files changed, 13 insertions, 28 deletions
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index d64f1657066..a301d65b60e 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); |