aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2014-03-18 11:36:45 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2014-03-18 11:36:53 -0400
commitf7271c44278352516ec66b2de311952ce330b6d5 (patch)
tree780a328ed198459a8d1968a8a759472becfb4bf1 /src
parent3bd261ca18c67eafe18088e58fab511e3b965418 (diff)
downloadpostgresql-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.c41
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);