aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/heap/heapam.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/heap/heapam.c')
-rw-r--r--src/backend/access/heap/heapam.c484
1 files changed, 81 insertions, 403 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index fb36736838a..91b1763d759 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -8,11 +8,10 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.117 2001/05/17 15:55:23 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.118 2001/06/09 18:16:55 tgl Exp $
*
*
* INTERFACE ROUTINES
- * heapgettup - fetch next heap tuple from a scan
* heap_open - open a heap relation by relationId
* heap_openr - open a heap relation by name
* heap_open[r]_nofail - same, but return NULL on failure instead of elog
@@ -33,60 +32,20 @@
* the POSTGRES heap access method used for all POSTGRES
* relations.
*
- * OLD COMMENTS
- * struct relscan hints: (struct should be made AM independent?)
- *
- * rs_ctid is the tid of the last tuple returned by getnext.
- * rs_ptid and rs_ntid are the tids of the previous and next tuples
- * returned by getnext, respectively. NULL indicates an end of
- * scan (either direction); NON indicates an unknow value.
- *
- * possible combinations:
- * rs_p rs_c rs_n interpretation
- * NULL NULL NULL empty scan
- * NULL NULL NON at begining of scan
- * NULL NULL t1 at begining of scan (with cached tid)
- * NON NULL NULL at end of scan
- * t1 NULL NULL at end of scan (with cached tid)
- * NULL t1 NULL just returned only tuple
- * NULL t1 NON just returned first tuple
- * NULL t1 t2 returned first tuple (with cached tid)
- * NON t1 NULL just returned last tuple
- * t2 t1 NULL returned last tuple (with cached tid)
- * t1 t2 NON in the middle of a forward scan
- * NON t2 t1 in the middle of a reverse scan
- * ti tj tk in the middle of a scan (w cached tid)
- *
- * Here NULL is ...tup == NULL && ...buf == InvalidBuffer,
- * and NON is ...tup == NULL && ...buf == UnknownBuffer.
- *
- * Currently, the NONTID values are not cached with their actual
- * values by getnext. Values may be cached by markpos since it stores
- * all three tids.
- *
- * NOTE: the calls to elog() must stop. Should decide on an interface
- * between the general and specific AM calls.
- *
- * XXX probably do not need a free tuple routine for heaps.
- * Huh? Free tuple is not necessary for tuples returned by scans, but
- * is necessary for tuples which are returned by
- * RelationGetTupleByItemPointer. -hirohama
- *
*-------------------------------------------------------------------------
*/
-
#include "postgres.h"
#include "access/heapam.h"
#include "access/hio.h"
#include "access/tuptoaster.h"
#include "access/valid.h"
+#include "access/xlogutils.h"
#include "catalog/catalog.h"
#include "miscadmin.h"
#include "utils/inval.h"
#include "utils/relcache.h"
-#include "access/xlogutils.h"
XLogRecPtr log_heap_move(Relation reln, Buffer oldbuf, ItemPointerData from,
Buffer newbuf, HeapTuple newtup);
@@ -116,7 +75,6 @@ initscan(HeapScanDesc scan,
unsigned nkeys,
ScanKey key)
{
-
/*
* Make sure we have up-to-date idea of number of blocks in relation.
* It is sufficient to do this once at scan start, since any tuples
@@ -125,50 +83,12 @@ initscan(HeapScanDesc scan,
*/
relation->rd_nblocks = RelationGetNumberOfBlocks(relation);
- if (relation->rd_nblocks == 0)
- {
-
- /*
- * relation is empty
- */
- scan->rs_ntup.t_datamcxt = scan->rs_ctup.t_datamcxt =
- scan->rs_ptup.t_datamcxt = NULL;
- scan->rs_ntup.t_data = scan->rs_ctup.t_data =
- scan->rs_ptup.t_data = NULL;
- scan->rs_nbuf = scan->rs_cbuf = scan->rs_pbuf = InvalidBuffer;
- }
- else if (atend)
- {
-
- /*
- * reverse scan
- */
- scan->rs_ntup.t_datamcxt = scan->rs_ctup.t_datamcxt = NULL;
- scan->rs_ntup.t_data = scan->rs_ctup.t_data = NULL;
- scan->rs_nbuf = scan->rs_cbuf = InvalidBuffer;
- scan->rs_ptup.t_datamcxt = NULL;
- scan->rs_ptup.t_data = NULL;
- scan->rs_pbuf = UnknownBuffer;
- }
- else
- {
-
- /*
- * forward scan
- */
- scan->rs_ctup.t_datamcxt = scan->rs_ptup.t_datamcxt = NULL;
- scan->rs_ctup.t_data = scan->rs_ptup.t_data = NULL;
- scan->rs_cbuf = scan->rs_pbuf = InvalidBuffer;
- scan->rs_ntup.t_datamcxt = NULL;
- scan->rs_ntup.t_data = NULL;
- scan->rs_nbuf = UnknownBuffer;
- } /* invalid too */
+ scan->rs_ctup.t_datamcxt = NULL;
+ scan->rs_ctup.t_data = NULL;
+ scan->rs_cbuf = InvalidBuffer;
/* we don't have a marked position... */
- ItemPointerSetInvalid(&(scan->rs_mptid));
ItemPointerSetInvalid(&(scan->rs_mctid));
- ItemPointerSetInvalid(&(scan->rs_mntid));
- ItemPointerSetInvalid(&(scan->rs_mcd));
/*
* copy the scan key, if appropriate
@@ -178,61 +98,21 @@ initscan(HeapScanDesc scan,
}
/* ----------------
- * unpinscan - code common to heap_rescan and heap_endscan
- * ----------------
- */
-static void
-unpinscan(HeapScanDesc scan)
-{
- if (BufferIsValid(scan->rs_pbuf))
- ReleaseBuffer(scan->rs_pbuf);
-
- /*
- * Scan will pin buffer once for each non-NULL tuple pointer (ptup,
- * ctup, ntup), so they have to be unpinned multiple times.
- */
- if (BufferIsValid(scan->rs_cbuf))
- ReleaseBuffer(scan->rs_cbuf);
-
- if (BufferIsValid(scan->rs_nbuf))
- ReleaseBuffer(scan->rs_nbuf);
-
- /*
- * we don't bother to clear rs_pbuf etc --- caller must reinitialize
- * them if scan descriptor is not being deleted.
- */
-}
-
-/* ------------------------------------------
- * nextpage
- *
- * figure out the next page to scan after the current page
- * taking into account of possible adjustment of degrees of
- * parallelism
- * ------------------------------------------
- */
-static int
-nextpage(int page, int dir)
-{
- return (dir < 0) ? page - 1 : page + 1;
-}
-
-/* ----------------
* heapgettup - fetch next heap tuple
*
* routine used by heap_getnext() which does most of the
* real work in scanning tuples.
*
- * The scan routines handle their own buffer lock/unlocking, so
- * there is no reason to request the buffer number unless
- * to want to perform some other operation with the result,
- * like pass it to another function.
+ * The passed-in *buffer must be either InvalidBuffer or the pinned
+ * current page of the scan. If we have to move to another page,
+ * we will unpin this buffer (if valid). On return, *buffer is either
+ * InvalidBuffer or the ID of a pinned buffer.
* ----------------
*/
static void
heapgettup(Relation relation,
- HeapTuple tuple,
int dir,
+ HeapTuple tuple,
Buffer *buffer,
Snapshot snapshot,
int nkeys,
@@ -245,8 +125,7 @@ heapgettup(Relation relation,
int lines;
OffsetNumber lineoff;
int linesleft;
- ItemPointer tid = (tuple->t_data == NULL) ?
- (ItemPointer) NULL : &(tuple->t_self);
+ ItemPointer tid;
/*
* increment access statistics
@@ -254,6 +133,8 @@ heapgettup(Relation relation,
IncrHeapAccessStat(local_heapgettup);
IncrHeapAccessStat(global_heapgettup);
+ tid = (tuple->t_data == NULL) ? (ItemPointer) NULL : &(tuple->t_self);
+
/*
* debugging stuff
*
@@ -280,7 +161,10 @@ heapgettup(Relation relation,
#endif /* !defined(HEAPDEBUGALL) */
if (!ItemPointerIsValid(tid))
+ {
Assert(!PointerIsValid(tid));
+ tid = NULL;
+ }
tuple->t_tableOid = relation->rd_id;
@@ -289,6 +173,9 @@ heapgettup(Relation relation,
*/
if (!(pages = relation->rd_nblocks))
{
+ if (BufferIsValid(*buffer))
+ ReleaseBuffer(*buffer);
+ *buffer = InvalidBuffer;
tuple->t_datamcxt = NULL;
tuple->t_data = NULL;
return;
@@ -299,22 +186,23 @@ heapgettup(Relation relation,
*/
if (!dir)
{
-
/*
- * ``no movement'' scan direction
+ * ``no movement'' scan direction: refetch same tuple
*/
- /* assume it is a valid TID XXX */
- if (ItemPointerIsValid(tid) == false)
+ if (tid == NULL)
{
+ if (BufferIsValid(*buffer))
+ ReleaseBuffer(*buffer);
*buffer = InvalidBuffer;
tuple->t_datamcxt = NULL;
tuple->t_data = NULL;
return;
}
- *buffer = RelationGetBufferWithBuffer(relation,
- ItemPointerGetBlockNumber(tid),
- *buffer);
+ *buffer = ReleaseAndReadBuffer(*buffer,
+ relation,
+ ItemPointerGetBlockNumber(tid),
+ false);
if (!BufferIsValid(*buffer))
elog(ERROR, "heapgettup: failed ReadBuffer");
@@ -333,12 +221,9 @@ heapgettup(Relation relation,
}
else if (dir < 0)
{
-
/*
* reverse scan direction
*/
- if (ItemPointerIsValid(tid) == false)
- tid = NULL;
if (tid == NULL)
{
page = pages - 1; /* final page */
@@ -349,12 +234,18 @@ heapgettup(Relation relation,
}
if (page < 0)
{
+ if (BufferIsValid(*buffer))
+ ReleaseBuffer(*buffer);
*buffer = InvalidBuffer;
+ tuple->t_datamcxt = NULL;
tuple->t_data = NULL;
return;
}
- *buffer = RelationGetBufferWithBuffer(relation, page, *buffer);
+ *buffer = ReleaseAndReadBuffer(*buffer,
+ relation,
+ page,
+ false);
if (!BufferIsValid(*buffer))
elog(ERROR, "heapgettup: failed ReadBuffer");
@@ -376,11 +267,10 @@ heapgettup(Relation relation,
}
else
{
-
/*
* forward scan direction
*/
- if (ItemPointerIsValid(tid) == false)
+ if (tid == NULL)
{
page = 0; /* first page */
lineoff = FirstOffsetNumber; /* first offnum */
@@ -394,14 +284,18 @@ heapgettup(Relation relation,
if (page >= pages)
{
+ if (BufferIsValid(*buffer))
+ ReleaseBuffer(*buffer);
*buffer = InvalidBuffer;
tuple->t_datamcxt = NULL;
tuple->t_data = NULL;
return;
}
- /* page and lineoff now reference the physically next tid */
- *buffer = RelationGetBufferWithBuffer(relation, page, *buffer);
+ *buffer = ReleaseAndReadBuffer(*buffer,
+ relation,
+ page,
+ false);
if (!BufferIsValid(*buffer))
elog(ERROR, "heapgettup: failed ReadBuffer");
@@ -409,6 +303,8 @@ heapgettup(Relation relation,
dp = (Page) BufferGetPage(*buffer);
lines = PageGetMaxOffsetNumber(dp);
+ /* page and lineoff now reference the physically next tid */
+
}
/* 'dir' is now non-zero */
@@ -469,13 +365,13 @@ heapgettup(Relation relation,
/*
* if we get here, it means we've exhausted the items on this page
- * and it's time to move to the next..
+ * and it's time to move to the next.
*/
LockBuffer(*buffer, BUFFER_LOCK_UNLOCK);
- page = nextpage(page, dir);
+ page = (dir < 0) ? (page - 1) : (page + 1);
/*
- * return NULL if we've exhausted all the pages..
+ * return NULL if we've exhausted all the pages
*/
if (page < 0 || page >= pages)
{
@@ -487,10 +383,13 @@ heapgettup(Relation relation,
return;
}
- *buffer = ReleaseAndReadBuffer(*buffer, relation, page, false);
-
+ *buffer = ReleaseAndReadBuffer(*buffer,
+ relation,
+ page,
+ false);
if (!BufferIsValid(*buffer))
elog(ERROR, "heapgettup: failed ReadBuffer");
+
LockBuffer(*buffer, BUFFER_LOCK_SHARE);
dp = (Page) BufferGetPage(*buffer);
lines = PageGetMaxOffsetNumber((Page) dp);
@@ -766,7 +665,6 @@ heap_beginscan(Relation relation,
scan = (HeapScanDesc) palloc(sizeof(HeapScanDescData));
scan->rs_rd = relation;
- scan->rs_atend = atend;
scan->rs_snapshot = snapshot;
scan->rs_nkeys = (short) nkeys;
@@ -793,7 +691,6 @@ heap_rescan(HeapScanDesc scan,
bool scanFromEnd,
ScanKey key)
{
-
/*
* increment access statistics
*/
@@ -803,12 +700,12 @@ heap_rescan(HeapScanDesc scan,
/*
* unpin scan buffers
*/
- unpinscan(scan);
+ if (BufferIsValid(scan->rs_cbuf))
+ ReleaseBuffer(scan->rs_cbuf);
/*
* reinitialize scan descriptor
*/
- scan->rs_atend = scanFromEnd;
initscan(scan, scan->rs_rd, scanFromEnd, scan->rs_nkeys, key);
}
@@ -822,7 +719,6 @@ heap_rescan(HeapScanDesc scan,
void
heap_endscan(HeapScanDesc scan)
{
-
/*
* increment access statistics
*/
@@ -834,7 +730,8 @@ heap_endscan(HeapScanDesc scan)
/*
* unpin scan buffers
*/
- unpinscan(scan);
+ if (BufferIsValid(scan->rs_cbuf))
+ ReleaseBuffer(scan->rs_cbuf);
/*
* decrement relation reference count and free scan descriptor storage
@@ -862,38 +759,20 @@ elog(DEBUG, "heap_getnext([%s,nkeys=%d],backw=%d) called", \
RelationGetRelationName(scan->rs_rd), scan->rs_nkeys, backw)
#define HEAPDEBUG_2 \
- elog(DEBUG, "heap_getnext called with backw (no tracing yet)")
-
-#define HEAPDEBUG_3 \
- elog(DEBUG, "heap_getnext returns NULL at end")
-
-#define HEAPDEBUG_4 \
- elog(DEBUG, "heap_getnext valid buffer UNPIN'd")
-
-#define HEAPDEBUG_5 \
- elog(DEBUG, "heap_getnext next tuple was cached")
-
-#define HEAPDEBUG_6 \
elog(DEBUG, "heap_getnext returning EOS")
-#define HEAPDEBUG_7 \
+#define HEAPDEBUG_3 \
elog(DEBUG, "heap_getnext returning tuple");
#else
#define HEAPDEBUG_1
#define HEAPDEBUG_2
#define HEAPDEBUG_3
-#define HEAPDEBUG_4
-#define HEAPDEBUG_5
-#define HEAPDEBUG_6
-#define HEAPDEBUG_7
#endif /* !defined(HEAPDEBUGALL) */
HeapTuple
-heap_getnext(HeapScanDesc scandesc, int backw)
+heap_getnext(HeapScanDesc scan, int backw)
{
- HeapScanDesc scan = scandesc;
-
/*
* increment access statistics
*/
@@ -908,165 +787,45 @@ heap_getnext(HeapScanDesc scandesc, int backw)
if (scan == NULL)
elog(ERROR, "heap_getnext: NULL relscan");
- /*
- * initialize return buffer to InvalidBuffer
- */
-
HEAPDEBUG_1; /* heap_getnext( info ) */
if (backw)
{
-
/*
* handle reverse scan
*/
- HEAPDEBUG_2; /* heap_getnext called with backw */
-
- if (scan->rs_ptup.t_data == scan->rs_ctup.t_data &&
- BufferIsInvalid(scan->rs_pbuf))
- return NULL;
-
- /*
- * Copy the "current" tuple/buffer to "next". Pin/unpin the
- * buffers accordingly
- */
- if (scan->rs_nbuf != scan->rs_cbuf)
- {
- if (BufferIsValid(scan->rs_nbuf))
- ReleaseBuffer(scan->rs_nbuf);
- if (BufferIsValid(scan->rs_cbuf))
- IncrBufferRefCount(scan->rs_cbuf);
- }
- scan->rs_ntup = scan->rs_ctup;
- scan->rs_nbuf = scan->rs_cbuf;
-
- if (scan->rs_ptup.t_data != NULL)
- {
- if (scan->rs_cbuf != scan->rs_pbuf)
- {
- if (BufferIsValid(scan->rs_cbuf))
- ReleaseBuffer(scan->rs_cbuf);
- if (BufferIsValid(scan->rs_pbuf))
- IncrBufferRefCount(scan->rs_pbuf);
- }
- scan->rs_ctup = scan->rs_ptup;
- scan->rs_cbuf = scan->rs_pbuf;
- }
- else
- { /* NONTUP */
-
- /*
- * Don't release scan->rs_cbuf at this point, because
- * heapgettup doesn't increase PrivateRefCount if it is
- * already set. On a backward scan, both rs_ctup and rs_ntup
- * usually point to the same buffer page, so
- * PrivateRefCount[rs_cbuf] should be 2 (or more, if for
- * instance ctup is stored in a TupleTableSlot). - 01/09/94
- */
-
- heapgettup(scan->rs_rd,
- &(scan->rs_ctup),
- -1,
- &(scan->rs_cbuf),
- scan->rs_snapshot,
- scan->rs_nkeys,
- scan->rs_key);
- }
+ heapgettup(scan->rs_rd,
+ -1,
+ &(scan->rs_ctup),
+ &(scan->rs_cbuf),
+ scan->rs_snapshot,
+ scan->rs_nkeys,
+ scan->rs_key);
if (scan->rs_ctup.t_data == NULL && !BufferIsValid(scan->rs_cbuf))
{
- if (BufferIsValid(scan->rs_pbuf))
- ReleaseBuffer(scan->rs_pbuf);
- scan->rs_ptup.t_datamcxt = NULL;
- scan->rs_ptup.t_data = NULL;
- scan->rs_pbuf = InvalidBuffer;
+ HEAPDEBUG_2; /* heap_getnext returning EOS */
return NULL;
}
-
- if (BufferIsValid(scan->rs_pbuf))
- ReleaseBuffer(scan->rs_pbuf);
- scan->rs_ptup.t_datamcxt = NULL;
- scan->rs_ptup.t_data = NULL;
- scan->rs_pbuf = UnknownBuffer;
-
}
else
{
-
/*
* handle forward scan
*/
- if (scan->rs_ctup.t_data == scan->rs_ntup.t_data &&
- BufferIsInvalid(scan->rs_nbuf))
- {
- HEAPDEBUG_3; /* heap_getnext returns NULL at end */
- return NULL;
- }
-
- /*
- * Copy the "current" tuple/buffer to "previous". Pin/unpin the
- * buffers accordingly
- */
- if (scan->rs_pbuf != scan->rs_cbuf)
- {
- if (BufferIsValid(scan->rs_pbuf))
- ReleaseBuffer(scan->rs_pbuf);
- if (BufferIsValid(scan->rs_cbuf))
- IncrBufferRefCount(scan->rs_cbuf);
- }
- scan->rs_ptup = scan->rs_ctup;
- scan->rs_pbuf = scan->rs_cbuf;
-
- if (scan->rs_ntup.t_data != NULL)
- {
- if (scan->rs_cbuf != scan->rs_nbuf)
- {
- if (BufferIsValid(scan->rs_cbuf))
- ReleaseBuffer(scan->rs_cbuf);
- if (BufferIsValid(scan->rs_nbuf))
- IncrBufferRefCount(scan->rs_nbuf);
- }
- scan->rs_ctup = scan->rs_ntup;
- scan->rs_cbuf = scan->rs_nbuf;
- HEAPDEBUG_5; /* heap_getnext next tuple was cached */
- }
- else
- { /* NONTUP */
-
- /*
- * Don't release scan->rs_cbuf at this point, because
- * heapgettup doesn't increase PrivateRefCount if it is
- * already set. On a forward scan, both rs_ctup and rs_ptup
- * usually point to the same buffer page, so
- * PrivateRefCount[rs_cbuf] should be 2 (or more, if for
- * instance ctup is stored in a TupleTableSlot). - 01/09/93
- */
-
- heapgettup(scan->rs_rd,
- &(scan->rs_ctup),
- 1,
- &scan->rs_cbuf,
- scan->rs_snapshot,
- scan->rs_nkeys,
- scan->rs_key);
- }
+ heapgettup(scan->rs_rd,
+ 1,
+ &(scan->rs_ctup),
+ &(scan->rs_cbuf),
+ scan->rs_snapshot,
+ scan->rs_nkeys,
+ scan->rs_key);
if (scan->rs_ctup.t_data == NULL && !BufferIsValid(scan->rs_cbuf))
{
- if (BufferIsValid(scan->rs_nbuf))
- ReleaseBuffer(scan->rs_nbuf);
- scan->rs_ntup.t_datamcxt = NULL;
- scan->rs_ntup.t_data = NULL;
- scan->rs_nbuf = InvalidBuffer;
- HEAPDEBUG_6; /* heap_getnext returning EOS */
+ HEAPDEBUG_2; /* heap_getnext returning EOS */
return NULL;
}
-
- if (BufferIsValid(scan->rs_nbuf))
- ReleaseBuffer(scan->rs_nbuf);
- scan->rs_ntup.t_datamcxt = NULL;
- scan->rs_ntup.t_data = NULL;
- scan->rs_nbuf = UnknownBuffer;
}
/*
@@ -1074,7 +833,7 @@ heap_getnext(HeapScanDesc scandesc, int backw)
* to the proper return buffer and return the tuple.
*/
- HEAPDEBUG_7; /* heap_getnext returning tuple */
+ HEAPDEBUG_3; /* heap_getnext returning tuple */
return ((scan->rs_ctup.t_data == NULL) ? NULL : &(scan->rs_ctup));
}
@@ -1987,7 +1746,6 @@ l3:
void
heap_markpos(HeapScanDesc scan)
{
-
/*
* increment access statistics
*/
@@ -1996,47 +1754,10 @@ heap_markpos(HeapScanDesc scan)
/* Note: no locking manipulations needed */
- if (scan->rs_ptup.t_data == NULL &&
- BufferIsUnknown(scan->rs_pbuf))
- { /* == NONTUP */
- scan->rs_ptup = scan->rs_ctup;
- heapgettup(scan->rs_rd,
- &(scan->rs_ptup),
- -1,
- &scan->rs_pbuf,
- scan->rs_snapshot,
- scan->rs_nkeys,
- scan->rs_key);
-
- }
- else if (scan->rs_ntup.t_data == NULL &&
- BufferIsUnknown(scan->rs_nbuf))
- { /* == NONTUP */
- scan->rs_ntup = scan->rs_ctup;
- heapgettup(scan->rs_rd,
- &(scan->rs_ntup),
- 1,
- &scan->rs_nbuf,
- scan->rs_snapshot,
- scan->rs_nkeys,
- scan->rs_key);
- }
-
- /*
- * Should not unpin the buffer pages. They may still be in use.
- */
- if (scan->rs_ptup.t_data != NULL)
- scan->rs_mptid = scan->rs_ptup.t_self;
- else
- ItemPointerSetInvalid(&scan->rs_mptid);
if (scan->rs_ctup.t_data != NULL)
scan->rs_mctid = scan->rs_ctup.t_self;
else
ItemPointerSetInvalid(&scan->rs_mctid);
- if (scan->rs_ntup.t_data != NULL)
- scan->rs_mntid = scan->rs_ntup.t_self;
- else
- ItemPointerSetInvalid(&scan->rs_mntid);
}
/* ----------------
@@ -2048,10 +1769,6 @@ heap_markpos(HeapScanDesc scan)
* cause the added tuples to be visible when the scan continues.
* Problems also arise if the TID's are rearranged!!!
*
- * Now pins buffer once for each valid tuple pointer (rs_ptup,
- * rs_ctup, rs_ntup) referencing it.
- * - 01/13/94
- *
* XXX might be better to do direct access instead of
* using the generality of heapgettup().
*
@@ -2063,7 +1780,6 @@ heap_markpos(HeapScanDesc scan)
void
heap_restrpos(HeapScanDesc scan)
{
-
/*
* increment access statistics
*/
@@ -2074,31 +1790,12 @@ heap_restrpos(HeapScanDesc scan)
/* Note: no locking manipulations needed */
- unpinscan(scan);
-
- /* force heapgettup to pin buffer for each loaded tuple */
- scan->rs_pbuf = InvalidBuffer;
+ /*
+ * unpin scan buffers
+ */
+ if (BufferIsValid(scan->rs_cbuf))
+ ReleaseBuffer(scan->rs_cbuf);
scan->rs_cbuf = InvalidBuffer;
- scan->rs_nbuf = InvalidBuffer;
-
- if (!ItemPointerIsValid(&scan->rs_mptid))
- {
- scan->rs_ptup.t_datamcxt = NULL;
- scan->rs_ptup.t_data = NULL;
- }
- else
- {
- scan->rs_ptup.t_self = scan->rs_mptid;
- scan->rs_ptup.t_datamcxt = NULL;
- scan->rs_ptup.t_data = (HeapTupleHeader) 0x1; /* for heapgettup */
- heapgettup(scan->rs_rd,
- &(scan->rs_ptup),
- 0,
- &(scan->rs_pbuf),
- false,
- 0,
- (ScanKey) NULL);
- }
if (!ItemPointerIsValid(&scan->rs_mctid))
{
@@ -2111,29 +1808,10 @@ heap_restrpos(HeapScanDesc scan)
scan->rs_ctup.t_datamcxt = NULL;
scan->rs_ctup.t_data = (HeapTupleHeader) 0x1; /* for heapgettup */
heapgettup(scan->rs_rd,
- &(scan->rs_ctup),
0,
+ &(scan->rs_ctup),
&(scan->rs_cbuf),
- false,
- 0,
- (ScanKey) NULL);
- }
-
- if (!ItemPointerIsValid(&scan->rs_mntid))
- {
- scan->rs_ntup.t_datamcxt = NULL;
- scan->rs_ntup.t_data = NULL;
- }
- else
- {
- scan->rs_ntup.t_datamcxt = NULL;
- scan->rs_ntup.t_self = scan->rs_mntid;
- scan->rs_ntup.t_data = (HeapTupleHeader) 0x1; /* for heapgettup */
- heapgettup(scan->rs_rd,
- &(scan->rs_ntup),
- 0,
- &scan->rs_nbuf,
- false,
+ scan->rs_snapshot,
0,
(ScanKey) NULL);
}