aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-07-31 20:09:10 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-07-31 20:09:10 +0000
commit09d3670df3e4593be1d2299a62d982829016b847 (patch)
tree7a62e91c1cf595d0334dd2c196d1c79835cc267b /src/backend/access
parent4cd72b53b9975bab5f4ca0792cf4f54c84829404 (diff)
downloadpostgresql-09d3670df3e4593be1d2299a62d982829016b847.tar.gz
postgresql-09d3670df3e4593be1d2299a62d982829016b847.zip
Change the relation_open protocol so that we obtain lock on a relation
(table or index) before trying to open its relcache entry. This fixes race conditions in which someone else commits a change to the relation's catalog entries while we are in process of doing relcache load. Problems of that ilk have been reported sporadically for years, but it was not really practical to fix until recently --- for instance, the recent addition of WAL-log support for in-place updates helped. Along the way, remove pg_am.amconcurrent: all AMs are now expected to support concurrent update.
Diffstat (limited to 'src/backend/access')
-rw-r--r--src/backend/access/gin/ginvacuum.c17
-rw-r--r--src/backend/access/gist/gistvacuum.c13
-rw-r--r--src/backend/access/heap/heapam.c66
-rw-r--r--src/backend/access/heap/tuptoaster.c31
-rw-r--r--src/backend/access/index/genam.c9
-rw-r--r--src/backend/access/index/indexam.c110
6 files changed, 103 insertions, 143 deletions
diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c
index c6551939a20..2bc80a26433 100644
--- a/src/backend/access/gin/ginvacuum.c
+++ b/src/backend/access/gin/ginvacuum.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gin/ginvacuum.c,v 1.4 2006/07/14 14:52:16 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gin/ginvacuum.c,v 1.5 2006/07/31 20:08:59 tgl Exp $
*-------------------------------------------------------------------------
*/
@@ -572,7 +572,7 @@ ginvacuumcleanup(PG_FUNCTION_ARGS) {
IndexVacuumInfo *info = (IndexVacuumInfo *) PG_GETARG_POINTER(0);
IndexBulkDeleteResult *stats = (IndexBulkDeleteResult *) PG_GETARG_POINTER(1);
Relation index = info->index;
- bool needLock = !RELATION_IS_LOCAL(index);
+ bool needLock;
BlockNumber npages,
blkno;
BlockNumber nFreePages,
@@ -591,10 +591,14 @@ ginvacuumcleanup(PG_FUNCTION_ARGS) {
*/
stats->num_index_tuples = info->num_heap_tuples;
- if (info->vacuum_full) {
- LockRelation(index, AccessExclusiveLock);
+ /*
+ * If vacuum full, we already have exclusive lock on the index.
+ * Otherwise, need lock unless it's local to this backend.
+ */
+ if (info->vacuum_full)
needLock = false;
- }
+ else
+ needLock = !RELATION_IS_LOCAL(index);
if (needLock)
LockRelationForExtension(index, ExclusiveLock);
@@ -653,9 +657,6 @@ ginvacuumcleanup(PG_FUNCTION_ARGS) {
if (needLock)
UnlockRelationForExtension(index, ExclusiveLock);
- if (info->vacuum_full)
- UnlockRelation(index, AccessExclusiveLock);
-
PG_RETURN_POINTER(stats);
}
diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c
index e3bff5147c2..37b5631b281 100644
--- a/src/backend/access/gist/gistvacuum.c
+++ b/src/backend/access/gist/gistvacuum.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gist/gistvacuum.c,v 1.25 2006/07/14 14:52:16 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gist/gistvacuum.c,v 1.26 2006/07/31 20:08:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -517,7 +517,7 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
GistVacuum gv;
ArrayTuple res;
- LockRelation(rel, AccessExclusiveLock);
+ /* note: vacuum.c already acquired AccessExclusiveLock on index */
gv.index = rel;
initGISTstate(&(gv.giststate), rel);
@@ -543,8 +543,12 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
(errmsg("index \"%s\" needs VACUUM FULL or REINDEX to finish crash recovery",
RelationGetRelationName(rel))));
+ /*
+ * If vacuum full, we already have exclusive lock on the index.
+ * Otherwise, need lock unless it's local to this backend.
+ */
if (info->vacuum_full)
- needLock = false; /* relation locked with AccessExclusiveLock */
+ needLock = false;
else
needLock = !RELATION_IS_LOCAL(rel);
@@ -613,9 +617,6 @@ gistvacuumcleanup(PG_FUNCTION_ARGS)
if (needLock)
UnlockRelationForExtension(rel, ExclusiveLock);
- if (info->vacuum_full)
- UnlockRelation(rel, AccessExclusiveLock);
-
PG_RETURN_POINTER(stats);
}
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 91460410bf9..f29407e8e5d 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.217 2006/07/14 14:52:17 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.218 2006/07/31 20:08:59 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -51,6 +51,7 @@
#include "pgstat.h"
#include "storage/procarray.h"
#include "utils/inval.h"
+#include "utils/lsyscache.h"
#include "utils/relcache.h"
@@ -687,15 +688,16 @@ relation_open(Oid relationId, LOCKMODE lockmode)
Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
+ /* Get the lock before trying to open the relcache entry */
+ if (lockmode != NoLock)
+ LockRelationOid(relationId, lockmode);
+
/* The relcache does all the real work... */
r = RelationIdGetRelation(relationId);
if (!RelationIsValid(r))
elog(ERROR, "could not open relation with OID %u", relationId);
- if (lockmode != NoLock)
- LockRelation(r, lockmode);
-
return r;
}
@@ -713,26 +715,38 @@ conditional_relation_open(Oid relationId, LOCKMODE lockmode, bool nowait)
Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
- /* The relcache does all the real work... */
- r = RelationIdGetRelation(relationId);
-
- if (!RelationIsValid(r))
- elog(ERROR, "could not open relation with OID %u", relationId);
-
+ /* Get the lock before trying to open the relcache entry */
if (lockmode != NoLock)
{
if (nowait)
{
- if (!ConditionalLockRelation(r, lockmode))
- ereport(ERROR,
- (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
- errmsg("could not obtain lock on relation \"%s\"",
- RelationGetRelationName(r))));
+ if (!ConditionalLockRelationOid(relationId, lockmode))
+ {
+ /* try to throw error by name; relation could be deleted... */
+ char *relname = get_rel_name(relationId);
+
+ if (relname)
+ ereport(ERROR,
+ (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
+ errmsg("could not obtain lock on relation \"%s\"",
+ relname)));
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
+ errmsg("could not obtain lock on relation with OID %u",
+ relationId)));
+ }
}
else
- LockRelation(r, lockmode);
+ LockRelationOid(relationId, lockmode);
}
+ /* The relcache does all the real work... */
+ r = RelationIdGetRelation(relationId);
+
+ if (!RelationIsValid(r))
+ elog(ERROR, "could not open relation with OID %u", relationId);
+
return r;
}
@@ -749,12 +763,12 @@ relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
/*
* Check for shared-cache-inval messages before trying to open the
- * relation. This is needed to cover the case where the name identifies a
- * rel that has been dropped and recreated since the start of our
+ * relation. This is needed to cover the case where the name identifies
+ * a rel that has been dropped and recreated since the start of our
* transaction: if we don't flush the old syscache entry then we'll latch
- * onto that entry and suffer an error when we do LockRelation. Note that
- * relation_open does not need to do this, since a relation's OID never
- * changes.
+ * onto that entry and suffer an error when we do RelationIdGetRelation.
+ * Note that relation_open does not need to do this, since a relation's
+ * OID never changes.
*
* We skip this if asked for NoLock, on the assumption that the caller has
* already ensured some appropriate lock is held.
@@ -772,7 +786,7 @@ relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
/* ----------------
* relation_close - close any relation
*
- * If lockmode is not "NoLock", we first release the specified lock.
+ * If lockmode is not "NoLock", we then release the specified lock.
*
* Note that it is often sensible to hold a lock beyond relation_close;
* in that case, the lock is released automatically at xact end.
@@ -781,13 +795,15 @@ relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
void
relation_close(Relation relation, LOCKMODE lockmode)
{
- Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
+ LockRelId relid = relation->rd_lockInfo.lockRelId;
- if (lockmode != NoLock)
- UnlockRelation(relation, lockmode);
+ Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
/* The relcache does the real work... */
RelationClose(relation);
+
+ if (lockmode != NoLock)
+ UnlockRelationId(&relid, lockmode);
}
diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c
index 11adf165c45..43ca366f0a6 100644
--- a/src/backend/access/heap/tuptoaster.c
+++ b/src/backend/access/heap/tuptoaster.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.62 2006/07/14 14:52:17 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.63 2006/07/31 20:08:59 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -1004,7 +1004,7 @@ toast_save_datum(Relation rel, Datum value)
*/
toastrel = heap_open(rel->rd_rel->reltoastrelid, RowExclusiveLock);
toasttupDesc = toastrel->rd_att;
- toastidx = index_open(toastrel->rd_rel->reltoastidxid);
+ toastidx = index_open(toastrel->rd_rel->reltoastidxid, RowExclusiveLock);
/*
* Create the varattrib reference
@@ -1044,12 +1044,6 @@ toast_save_datum(Relation rel, Datum value)
data_todo = VARATT_SIZE(value) - VARHDRSZ;
/*
- * We must explicitly lock the toast index because we aren't using an
- * index scan here.
- */
- LockRelation(toastidx, RowExclusiveLock);
-
- /*
* Split up the item into chunks
*/
while (data_todo > 0)
@@ -1098,8 +1092,7 @@ toast_save_datum(Relation rel, Datum value)
/*
* Done - close toast relation and return the reference
*/
- UnlockRelation(toastidx, RowExclusiveLock);
- index_close(toastidx);
+ index_close(toastidx, RowExclusiveLock);
heap_close(toastrel, RowExclusiveLock);
return PointerGetDatum(result);
@@ -1130,7 +1123,7 @@ toast_delete_datum(Relation rel, Datum value)
*/
toastrel = heap_open(attr->va_content.va_external.va_toastrelid,
RowExclusiveLock);
- toastidx = index_open(toastrel->rd_rel->reltoastidxid);
+ toastidx = index_open(toastrel->rd_rel->reltoastidxid, RowExclusiveLock);
/*
* Setup a scan key to fetch from the index by va_valueid (we don't
@@ -1144,7 +1137,7 @@ toast_delete_datum(Relation rel, Datum value)
/*
* Find the chunks by index
*/
- toastscan = index_beginscan(toastrel, toastidx, true,
+ toastscan = index_beginscan(toastrel, toastidx,
SnapshotToast, 1, &toastkey);
while ((toasttup = index_getnext(toastscan, ForwardScanDirection)) != NULL)
{
@@ -1158,7 +1151,7 @@ toast_delete_datum(Relation rel, Datum value)
* End scan and close relations
*/
index_endscan(toastscan);
- index_close(toastidx);
+ index_close(toastidx, RowExclusiveLock);
heap_close(toastrel, RowExclusiveLock);
}
@@ -1202,7 +1195,7 @@ toast_fetch_datum(varattrib *attr)
toastrel = heap_open(attr->va_content.va_external.va_toastrelid,
AccessShareLock);
toasttupDesc = toastrel->rd_att;
- toastidx = index_open(toastrel->rd_rel->reltoastidxid);
+ toastidx = index_open(toastrel->rd_rel->reltoastidxid, AccessShareLock);
/*
* Setup a scan key to fetch from the index by va_valueid
@@ -1221,7 +1214,7 @@ toast_fetch_datum(varattrib *attr)
*/
nextidx = 0;
- toastscan = index_beginscan(toastrel, toastidx, true,
+ toastscan = index_beginscan(toastrel, toastidx,
SnapshotToast, 1, &toastkey);
while ((ttup = index_getnext(toastscan, ForwardScanDirection)) != NULL)
{
@@ -1282,7 +1275,7 @@ toast_fetch_datum(varattrib *attr)
* End scan and close relations
*/
index_endscan(toastscan);
- index_close(toastidx);
+ index_close(toastidx, AccessShareLock);
heap_close(toastrel, AccessShareLock);
return result;
@@ -1355,7 +1348,7 @@ toast_fetch_datum_slice(varattrib *attr, int32 sliceoffset, int32 length)
toastrel = heap_open(attr->va_content.va_external.va_toastrelid,
AccessShareLock);
toasttupDesc = toastrel->rd_att;
- toastidx = index_open(toastrel->rd_rel->reltoastidxid);
+ toastidx = index_open(toastrel->rd_rel->reltoastidxid, AccessShareLock);
/*
* Setup a scan key to fetch from the index. This is either two keys or
@@ -1396,7 +1389,7 @@ toast_fetch_datum_slice(varattrib *attr, int32 sliceoffset, int32 length)
* The index is on (valueid, chunkidx) so they will come in order
*/
nextidx = startchunk;
- toastscan = index_beginscan(toastrel, toastidx, true,
+ toastscan = index_beginscan(toastrel, toastidx,
SnapshotToast, nscankeys, toastkey);
while ((ttup = index_getnext(toastscan, ForwardScanDirection)) != NULL)
{
@@ -1461,7 +1454,7 @@ toast_fetch_datum_slice(varattrib *attr, int32 sliceoffset, int32 length)
* End scan and close relations
*/
index_endscan(toastscan);
- index_close(toastidx);
+ index_close(toastidx, AccessShareLock);
heap_close(toastrel, AccessShareLock);
return result;
diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c
index 399386c8567..347d2b5365a 100644
--- a/src/backend/access/index/genam.c
+++ b/src/backend/access/index/genam.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.57 2006/07/03 22:45:37 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.58 2006/07/31 20:08:59 tgl Exp $
*
* NOTES
* many of the old access method routines have been turned into
@@ -87,7 +87,6 @@ RelationGetIndexScan(Relation indexRelation,
scan->keyData = NULL;
scan->is_multiscan = false; /* caller may change this */
- scan->have_lock = false; /* ditto */
scan->kill_prior_tuple = false;
scan->ignore_killed_tuples = true; /* default setting */
@@ -182,7 +181,7 @@ systable_beginscan(Relation heapRelation,
if (indexOK &&
!IgnoreSystemIndexes &&
!ReindexIsProcessingIndex(indexId))
- irel = index_open(indexId);
+ irel = index_open(indexId, AccessShareLock);
else
irel = NULL;
@@ -207,7 +206,7 @@ systable_beginscan(Relation heapRelation,
key[i].sk_attno = i + 1;
}
- sysscan->iscan = index_beginscan(heapRelation, irel, true,
+ sysscan->iscan = index_beginscan(heapRelation, irel,
snapshot, nkeys, key);
sysscan->scan = NULL;
}
@@ -253,7 +252,7 @@ systable_endscan(SysScanDesc sysscan)
if (sysscan->irel)
{
index_endscan(sysscan->iscan);
- index_close(sysscan->irel);
+ index_close(sysscan->irel, AccessShareLock);
}
else
heap_endscan(sysscan->scan);
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index 900b34263d8..2663876f494 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -8,11 +8,10 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.93 2006/05/07 01:21:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.94 2006/07/31 20:08:59 tgl Exp $
*
* INTERFACE ROUTINES
* index_open - open an index relation by relation OID
- * index_openrv - open an index relation specified by a RangeVar
* index_close - close an index relation
* index_beginscan - start a scan of an index with amgettuple
* index_beginscan_multi - start a scan of an index with amgetmulti
@@ -111,7 +110,6 @@ do { \
} while(0)
static IndexScanDesc index_beginscan_internal(Relation indexRelation,
- bool need_index_lock,
int nkeys, ScanKey key);
@@ -123,26 +121,23 @@ static IndexScanDesc index_beginscan_internal(Relation indexRelation,
/* ----------------
* index_open - open an index relation by relation OID
*
- * Note: we acquire no lock on the index. A lock is not needed when
- * simply examining the index reldesc; the index's schema information
- * is considered to be protected by the lock that the caller had better
- * be holding on the parent relation. Some type of lock should be
- * obtained on the index before physically accessing it, however.
- * This is handled automatically for most uses by index_beginscan
- * and index_endscan for scan cases, or by ExecOpenIndices and
- * ExecCloseIndices for update cases. Other callers will need to
- * obtain their own locks.
+ * If lockmode is not "NoLock", the specified kind of lock is
+ * obtained on the index. (Generally, NoLock should only be
+ * used if the caller knows it has some appropriate lock on the
+ * index already.)
+ *
+ * An error is raised if the index does not exist.
*
* This is a convenience routine adapted for indexscan use.
* Some callers may prefer to use relation_open directly.
* ----------------
*/
Relation
-index_open(Oid relationId)
+index_open(Oid relationId, LOCKMODE lockmode)
{
Relation r;
- r = relation_open(relationId, NoLock);
+ r = relation_open(relationId, lockmode);
if (r->rd_rel->relkind != RELKIND_INDEX)
ereport(ERROR,
@@ -156,41 +151,26 @@ index_open(Oid relationId)
}
/* ----------------
- * index_openrv - open an index relation specified
- * by a RangeVar node
+ * index_close - close an index relation
*
- * As above, but relation is specified by a RangeVar.
- * ----------------
- */
-Relation
-index_openrv(const RangeVar *relation)
-{
- Relation r;
-
- r = relation_openrv(relation, NoLock);
-
- if (r->rd_rel->relkind != RELKIND_INDEX)
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is not an index",
- RelationGetRelationName(r))));
-
- pgstat_initstats(&r->pgstat_info, r);
-
- return r;
-}
-
-/* ----------------
- * index_close - close a index relation
+ * If lockmode is not "NoLock", we then release the specified lock.
*
- * presently the relcache routines do all the work we need
- * to open/close index relations.
+ * Note that it is often sensible to hold a lock beyond index_close;
+ * in that case, the lock is released automatically at xact end.
* ----------------
*/
void
-index_close(Relation relation)
+index_close(Relation relation, LOCKMODE lockmode)
{
+ LockRelId relid = relation->rd_lockInfo.lockRelId;
+
+ Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
+
+ /* The relcache does the real work... */
RelationClose(relation);
+
+ if (lockmode != NoLock)
+ UnlockRelationId(&relid, lockmode);
}
/* ----------------
@@ -229,24 +209,18 @@ index_insert(Relation indexRelation,
* index_getnext on this scan; index_getnext_indexitem will not use the
* heapRelation link (nor the snapshot). However, the caller had better
* be holding some kind of lock on the heap relation in any case, to ensure
- * no one deletes it (or the index) out from under us.
- *
- * Most callers should pass need_index_lock = true to cause the index code
- * to take AccessShareLock on the index for the duration of the scan. But
- * if it is known that a lock is already held on the index, pass false to
- * skip taking an unnecessary lock.
+ * no one deletes it (or the index) out from under us. Caller must also
+ * be holding a lock on the index.
*/
IndexScanDesc
index_beginscan(Relation heapRelation,
Relation indexRelation,
- bool need_index_lock,
Snapshot snapshot,
int nkeys, ScanKey key)
{
IndexScanDesc scan;
- scan = index_beginscan_internal(indexRelation, need_index_lock,
- nkeys, key);
+ scan = index_beginscan_internal(indexRelation, nkeys, key);
/*
* Save additional parameters into the scandesc. Everything else was set
@@ -267,14 +241,12 @@ index_beginscan(Relation heapRelation,
*/
IndexScanDesc
index_beginscan_multi(Relation indexRelation,
- bool need_index_lock,
Snapshot snapshot,
int nkeys, ScanKey key)
{
IndexScanDesc scan;
- scan = index_beginscan_internal(indexRelation, need_index_lock,
- nkeys, key);
+ scan = index_beginscan_internal(indexRelation, nkeys, key);
/*
* Save additional parameters into the scandesc. Everything else was set
@@ -291,33 +263,18 @@ index_beginscan_multi(Relation indexRelation,
*/
static IndexScanDesc
index_beginscan_internal(Relation indexRelation,
- bool need_index_lock,
int nkeys, ScanKey key)
{
IndexScanDesc scan;
FmgrInfo *procedure;
RELATION_CHECKS;
-
- RelationIncrementReferenceCount(indexRelation);
-
- /*
- * Acquire AccessShareLock for the duration of the scan, unless caller
- * says it already has lock on the index.
- *
- * Note: we could get an SI inval message here and consequently have to
- * rebuild the relcache entry. The refcount increment above ensures that
- * we will rebuild it and not just flush it...
- */
- if (need_index_lock)
- LockRelation(indexRelation, AccessShareLock);
+ GET_REL_PROCEDURE(ambeginscan);
/*
- * LockRelation can clean rd_aminfo structure, so fill procedure after
- * LockRelation
+ * We hold a reference count to the relcache entry throughout the scan.
*/
-
- GET_REL_PROCEDURE(ambeginscan);
+ RelationIncrementReferenceCount(indexRelation);
/*
* Tell the AM to open a scan.
@@ -328,9 +285,6 @@ index_beginscan_internal(Relation indexRelation,
Int32GetDatum(nkeys),
PointerGetDatum(key)));
- /* Save flag to tell index_endscan whether to release lock */
- scan->have_lock = need_index_lock;
-
return scan;
}
@@ -390,11 +344,7 @@ index_endscan(IndexScanDesc scan)
/* End the AM's scan */
FunctionCall1(procedure, PointerGetDatum(scan));
- /* Release index lock and refcount acquired by index_beginscan */
-
- if (scan->have_lock)
- UnlockRelation(scan->indexRelation, AccessShareLock);
-
+ /* Release index refcount acquired by index_beginscan */
RelationDecrementReferenceCount(scan->indexRelation);
/* Release the scan data structure itself */