1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-23 03:21:12 +03:00

New HeapTuple structure/interface.

This commit is contained in:
Vadim B. Mikheev
1998-11-27 19:52:36 +00:00
parent 2435c7d501
commit 6beba218d7
65 changed files with 834 additions and 850 deletions

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.37 1998/10/12 00:53:30 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.38 1998/11/27 19:51:36 vadim Exp $
*
*
* INTERFACE ROUTINES
@ -120,7 +120,8 @@ initscan(HeapScanDesc scan,
* relation is empty
* ----------------
*/
scan->rs_ntup = scan->rs_ctup = scan->rs_ptup = 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)
@ -129,9 +130,9 @@ initscan(HeapScanDesc scan,
* reverse scan
* ----------------
*/
scan->rs_ntup = scan->rs_ctup = NULL;
scan->rs_ntup.t_data = scan->rs_ctup.t_data = NULL;
scan->rs_nbuf = scan->rs_cbuf = InvalidBuffer;
scan->rs_ptup = NULL;
scan->rs_ptup.t_data = NULL;
scan->rs_pbuf = UnknownBuffer;
}
else
@ -140,9 +141,9 @@ initscan(HeapScanDesc scan,
* forward scan
* ----------------
*/
scan->rs_ctup = scan->rs_ptup = NULL;
scan->rs_ctup.t_data = scan->rs_ptup.t_data = NULL;
scan->rs_cbuf = scan->rs_pbuf = InvalidBuffer;
scan->rs_ntup = NULL;
scan->rs_ntup.t_data = NULL;
scan->rs_nbuf = UnknownBuffer;
} /* invalid too */
@ -209,23 +210,24 @@ nextpage(int page, int dir)
* like pass it to another function.
* ----------------
*/
static HeapTuple
static void
heapgettup(Relation relation,
ItemPointer tid,
HeapTuple tuple,
int dir,
Buffer *buf,
Snapshot snapshot,
int nkeys,
ScanKey key)
{
ItemId lpp;
Page dp;
int page;
int pages;
int lines;
HeapTuple rtup;
OffsetNumber lineoff;
int linesleft;
ItemId lpp;
Page dp;
int page;
int pages;
int lines;
OffsetNumber lineoff;
int linesleft;
ItemPointer tid = (tuple->t_data == NULL) ?
(ItemPointer) NULL : &(tuple->t_self);
/* ----------------
* increment access statistics
@ -268,7 +270,10 @@ heapgettup(Relation relation,
* ----------------
*/
if (!(pages = relation->rd_nblocks))
return NULL;
{
tuple->t_data = NULL;
return;
}
/* ----------------
* calculate next starting lineoff, given scan direction
@ -284,7 +289,8 @@ heapgettup(Relation relation,
if (ItemPointerIsValid(tid) == false)
{
*buf = InvalidBuffer;
return NULL;
tuple->t_data = NULL;
return;
}
*buf = RelationGetBufferWithBuffer(relation,
ItemPointerGetBlockNumber(tid),
@ -299,8 +305,9 @@ heapgettup(Relation relation,
lineoff = ItemPointerGetOffsetNumber(tid);
lpp = PageGetItemId(dp, lineoff);
rtup = (HeapTuple) PageGetItem((Page) dp, lpp);
return rtup;
tuple->t_data = (HeapTupleHeader) PageGetItem((Page) dp, lpp);
tuple->t_len = ItemIdGetLength(lpp);
return;
}
else if (dir < 0)
@ -322,7 +329,8 @@ heapgettup(Relation relation,
if (page < 0)
{
*buf = InvalidBuffer;
return NULL;
tuple->t_data = NULL;
return;
}
*buf = RelationGetBufferWithBuffer(relation, page, *buf);
@ -366,7 +374,8 @@ heapgettup(Relation relation,
if (page >= pages)
{
*buf = InvalidBuffer;
return NULL;
tuple->t_data = NULL;
return;
}
/* page and lineoff now reference the physically next tid */
@ -402,26 +411,19 @@ heapgettup(Relation relation,
{
while (linesleft >= 0)
{
/* ----------------
* if current tuple qualifies, return it.
* ----------------
*/
HeapTupleSatisfies(lpp, relation, *buf, (PageHeader) dp,
snapshot, nkeys, key, rtup);
if (rtup != NULL)
if (ItemIdIsUsed(lpp))
{
ItemPointer iptr = &(rtup->t_ctid);
if (ItemPointerGetBlockNumber(iptr) != page)
{
/*
* set block id to the correct page number --- this is
* a hack to support the virtual fragment concept
*/
ItemPointerSetBlockNumber(iptr, page);
}
return rtup;
tuple->t_data = (HeapTupleHeader) PageGetItem((Page) dp, lpp);
tuple->t_len = ItemIdGetLength(lpp);
ItemPointerSet(&(tuple->t_self), page, lineoff);
/* ----------------
* if current tuple qualifies, return it.
* ----------------
*/
HeapTupleSatisfies(tuple, relation, *buf, (PageHeader) dp,
snapshot, nkeys, key);
if (tuple->t_data != NULL)
return;
}
/* ----------------
@ -432,11 +434,12 @@ heapgettup(Relation relation,
if (dir < 0)
{
--lpp; /* move back in this page's ItemId array */
--lineoff;
}
else
{
++lpp; /* move forward in this page's ItemId
* array */
++lpp; /* move forward in this page's ItemId array */
++lineoff;
}
}
@ -456,7 +459,8 @@ heapgettup(Relation relation,
if (BufferIsValid(*buf))
ReleaseBuffer(*buf);
*buf = InvalidBuffer;
return NULL;
tuple->t_data = NULL;
return;
}
*buf = ReleaseAndReadBuffer(*buf, relation, page);
@ -466,12 +470,18 @@ heapgettup(Relation relation,
elog(ERROR, "heapgettup: failed ReadBuffer");
#endif
dp = (Page) BufferGetPage(*buf);
lines = lineoff = PageGetMaxOffsetNumber((Page) dp);
lines = PageGetMaxOffsetNumber((Page) dp);
linesleft = lines - 1;
if (dir < 0)
lpp = PageGetItemId(dp, lineoff);
{
lineoff = lines;
lpp = PageGetItemId(dp, lines);
}
else
{
lineoff = FirstOffsetNumber;
lpp = PageGetItemId(dp, FirstOffsetNumber);
}
}
}
@ -786,7 +796,7 @@ heap_getnext(HeapScanDesc scandesc, int backw)
*/
HEAPDEBUG_2; /* heap_getnext called with backw */
if (scan->rs_ptup == scan->rs_ctup &&
if (scan->rs_ptup.t_data == scan->rs_ctup.t_data &&
BufferIsInvalid(scan->rs_pbuf))
{
if (BufferIsValid(scan->rs_nbuf))
@ -808,7 +818,7 @@ heap_getnext(HeapScanDesc scandesc, int backw)
scan->rs_ntup = scan->rs_ctup;
scan->rs_nbuf = scan->rs_cbuf;
if (scan->rs_ptup != NULL)
if (scan->rs_ptup.t_data != NULL)
{
if (scan->rs_cbuf != scan->rs_pbuf)
{
@ -822,11 +832,6 @@ heap_getnext(HeapScanDesc scandesc, int backw)
}
else
{ /* NONTUP */
ItemPointer iptr;
iptr = (scan->rs_ctup != NULL) ?
&(scan->rs_ctup->t_ctid) : (ItemPointer) NULL;
/*
* Don't release scan->rs_cbuf at this point, because
* heapgettup doesn't increase PrivateRefCount if it is
@ -836,32 +841,31 @@ heap_getnext(HeapScanDesc scandesc, int backw)
* instance ctup is stored in a TupleTableSlot). - 01/09/94
*/
scan->rs_ctup = (HeapTuple)
heapgettup(scan->rs_rd,
iptr,
-1,
&(scan->rs_cbuf),
scan->rs_snapshot,
scan->rs_nkeys,
scan->rs_key);
heapgettup(scan->rs_rd,
&(scan->rs_ctup),
-1,
&(scan->rs_cbuf),
scan->rs_snapshot,
scan->rs_nkeys,
scan->rs_key);
}
if (scan->rs_ctup == NULL && !BufferIsValid(scan->rs_cbuf))
if (scan->rs_ctup.t_data == NULL && !BufferIsValid(scan->rs_cbuf))
{
if (BufferIsValid(scan->rs_pbuf))
ReleaseBuffer(scan->rs_pbuf);
scan->rs_ptup = NULL;
scan->rs_ptup.t_data = NULL;
scan->rs_pbuf = InvalidBuffer;
if (BufferIsValid(scan->rs_nbuf))
ReleaseBuffer(scan->rs_nbuf);
scan->rs_ntup = NULL;
scan->rs_ntup.t_data = NULL;
scan->rs_nbuf = InvalidBuffer;
return NULL;
}
if (BufferIsValid(scan->rs_pbuf))
ReleaseBuffer(scan->rs_pbuf);
scan->rs_ptup = NULL;
scan->rs_ptup.t_data = NULL;
scan->rs_pbuf = UnknownBuffer;
}
@ -871,7 +875,7 @@ heap_getnext(HeapScanDesc scandesc, int backw)
* handle forward scan
* ----------------
*/
if (scan->rs_ctup == scan->rs_ntup &&
if (scan->rs_ctup.t_data == scan->rs_ntup.t_data &&
BufferIsInvalid(scan->rs_nbuf))
{
if (BufferIsValid(scan->rs_pbuf))
@ -894,7 +898,7 @@ heap_getnext(HeapScanDesc scandesc, int backw)
scan->rs_ptup = scan->rs_ctup;
scan->rs_pbuf = scan->rs_cbuf;
if (scan->rs_ntup != NULL)
if (scan->rs_ntup.t_data != NULL)
{
if (scan->rs_cbuf != scan->rs_nbuf)
{
@ -909,11 +913,6 @@ heap_getnext(HeapScanDesc scandesc, int backw)
}
else
{ /* NONTUP */
ItemPointer iptr;
iptr = (scan->rs_ctup != NULL) ?
&scan->rs_ctup->t_ctid : (ItemPointer) NULL;
/*
* Don't release scan->rs_cbuf at this point, because
* heapgettup doesn't increase PrivateRefCount if it is
@ -923,25 +922,24 @@ heap_getnext(HeapScanDesc scandesc, int backw)
* instance ctup is stored in a TupleTableSlot). - 01/09/93
*/
scan->rs_ctup = (HeapTuple)
heapgettup(scan->rs_rd,
iptr,
1,
&scan->rs_cbuf,
scan->rs_snapshot,
scan->rs_nkeys,
scan->rs_key);
heapgettup(scan->rs_rd,
&(scan->rs_ctup),
1,
&scan->rs_cbuf,
scan->rs_snapshot,
scan->rs_nkeys,
scan->rs_key);
}
if (scan->rs_ctup == NULL && !BufferIsValid(scan->rs_cbuf))
if (scan->rs_ctup.t_data == NULL && !BufferIsValid(scan->rs_cbuf))
{
if (BufferIsValid(scan->rs_nbuf))
ReleaseBuffer(scan->rs_nbuf);
scan->rs_ntup = NULL;
scan->rs_ntup.t_data = NULL;
scan->rs_nbuf = InvalidBuffer;
if (BufferIsValid(scan->rs_pbuf))
ReleaseBuffer(scan->rs_pbuf);
scan->rs_ptup = NULL;
scan->rs_ptup.t_data = NULL;
scan->rs_pbuf = InvalidBuffer;
HEAPDEBUG_6; /* heap_getnext returning EOS */
return NULL;
@ -949,7 +947,7 @@ heap_getnext(HeapScanDesc scandesc, int backw)
if (BufferIsValid(scan->rs_nbuf))
ReleaseBuffer(scan->rs_nbuf);
scan->rs_ntup = NULL;
scan->rs_ntup.t_data = NULL;
scan->rs_nbuf = UnknownBuffer;
}
@ -961,7 +959,7 @@ heap_getnext(HeapScanDesc scandesc, int backw)
HEAPDEBUG_7; /* heap_getnext returning tuple */
return scan->rs_ctup;
return ((scan->rs_ctup.t_data == NULL) ? NULL : &(scan->rs_ctup));
}
/* ----------------
@ -972,23 +970,23 @@ heap_getnext(HeapScanDesc scandesc, int backw)
* Because this is not part of a scan, there is no way to
* automatically lock/unlock the shared buffers.
* For this reason, we require that the user retrieve the buffer
* value, and they are required to BuffferRelease() it when they
* value, and they are required to BufferRelease() it when they
* are done. If they want to make a copy of it before releasing it,
* they can call heap_copytyple().
* ----------------
*/
HeapTuple
void
heap_fetch(Relation relation,
Snapshot snapshot,
ItemPointer tid,
HeapTuple tuple,
Buffer *userbuf)
{
ItemId lp;
Buffer buffer;
PageHeader dp;
HeapTuple tuple;
OffsetNumber offnum;
ItemId lp;
Buffer buffer;
PageHeader dp;
ItemPointer tid = &(tuple->t_self);
OffsetNumber offnum;
AssertMacro(PointerIsValid(userbuf)); /* see comments above */
@ -1038,18 +1036,21 @@ heap_fetch(Relation relation,
Assert(ItemIdIsUsed(lp));
tuple->t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
tuple->t_len = ItemIdGetLength(lp);
/* ----------------
* check time qualification of tid
* ----------------
*/
HeapTupleSatisfies(lp, relation, buffer, dp,
snapshot, 0, (ScanKey) NULL, tuple);
HeapTupleSatisfies(tuple, relation, buffer, dp,
snapshot, 0, (ScanKey) NULL);
if (tuple == NULL)
if (tuple->t_data == NULL)
{
ReleaseBuffer(buffer);
return NULL;
return;
}
/* ----------------
@ -1062,7 +1063,7 @@ heap_fetch(Relation relation,
*userbuf = buffer; /* user is required to ReleaseBuffer()
* this */
return tuple;
return;
}
/* ----------------
@ -1107,19 +1108,19 @@ heap_insert(Relation relation, HeapTuple tup)
* another).
* ----------------
*/
if (!OidIsValid(tup->t_oid))
if (!OidIsValid(tup->t_data->t_oid))
{
tup->t_oid = newoid();
LastOidProcessed = tup->t_oid;
tup->t_data->t_oid = newoid();
LastOidProcessed = tup->t_data->t_oid;
}
else
CheckMaxObjectId(tup->t_oid);
CheckMaxObjectId(tup->t_data->t_oid);
TransactionIdStore(GetCurrentTransactionId(), &(tup->t_xmin));
tup->t_cmin = GetCurrentCommandId();
StoreInvalidTransactionId(&(tup->t_xmax));
tup->t_infomask &= ~(HEAP_XACT_MASK);
tup->t_infomask |= HEAP_XMAX_INVALID;
TransactionIdStore(GetCurrentTransactionId(), &(tup->t_data->t_xmin));
tup->t_data->t_cmin = GetCurrentCommandId();
StoreInvalidTransactionId(&(tup->t_data->t_xmax));
tup->t_data->t_infomask &= ~(HEAP_XACT_MASK);
tup->t_data->t_infomask |= HEAP_XMAX_INVALID;
doinsert(relation, tup);
@ -1134,7 +1135,7 @@ heap_insert(Relation relation, HeapTuple tup)
RelationInvalidateHeapTuple(relation, tup);
}
return tup->t_oid;
return tup->t_data->t_oid;
}
/* ----------------
@ -1146,10 +1147,10 @@ heap_insert(Relation relation, HeapTuple tup)
int
heap_delete(Relation relation, ItemPointer tid)
{
ItemId lp;
HeapTuple tp;
PageHeader dp;
Buffer buf;
ItemId lp;
HeapTupleData tp;
PageHeader dp;
Buffer buf;
/* ----------------
* increment access statistics
@ -1186,9 +1187,11 @@ heap_delete(Relation relation, ItemPointer tid)
* Just like test against non-functional updates we try to catch
* non-functional delete attempts. - vadim 05/05/97
*/
tp = (HeapTuple) PageGetItem((Page) dp, lp);
Assert(HeapTupleIsValid(tp));
if (TupleUpdatedByCurXactAndCmd(tp))
tp.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
tp.t_len = ItemIdGetLength(lp);
tp.t_self = *tid;
if (TupleUpdatedByCurXactAndCmd(&tp))
{
/*
@ -1204,9 +1207,9 @@ heap_delete(Relation relation, ItemPointer tid)
* check that we're deleteing a valid item
* ----------------
*/
HeapTupleSatisfies(lp, relation, buf, dp,
false, 0, (ScanKey) NULL, tp);
if (!tp)
HeapTupleSatisfies((&tp), relation, buf, dp,
false, 0, (ScanKey) NULL);
if (!(tp.t_data))
{
/* XXX call something else */
@ -1225,15 +1228,15 @@ heap_delete(Relation relation, ItemPointer tid)
* store transaction information of xact deleting the tuple
* ----------------
*/
TransactionIdStore(GetCurrentTransactionId(), &(tp->t_xmax));
tp->t_cmax = GetCurrentCommandId();
tp->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_XMAX_INVALID);
TransactionIdStore(GetCurrentTransactionId(), &(tp.t_data->t_xmax));
tp.t_data->t_cmax = GetCurrentCommandId();
tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_XMAX_INVALID);
/* ----------------
* invalidate caches
* ----------------
*/
RelationInvalidateHeapTuple(relation, tp);
RelationInvalidateHeapTuple(relation, &tp);
WriteBuffer(buf);
if (IsSystemRelationName(RelationGetRelationName(relation)->data))
@ -1257,13 +1260,12 @@ heap_delete(Relation relation, ItemPointer tid)
* ----------------
*/
int
heap_replace(Relation relation, ItemPointer otid, HeapTuple replace_tuple)
heap_replace(Relation relation, ItemPointer otid, HeapTuple newtup)
{
ItemId lp;
HeapTuple old_tuple;
Page dp;
Buffer buffer;
HeapTuple tuple;
ItemId lp;
HeapTupleData oldtup;
Page dp;
Buffer buffer;
/* ----------------
* increment access statistics
@ -1286,13 +1288,8 @@ heap_replace(Relation relation, ItemPointer otid, HeapTuple replace_tuple)
RelationSetLockForWrite(relation);
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(otid));
#ifndef NO_BUFFERISVALID
if (!BufferIsValid(buffer))
{
/* XXX L_SH better ??? */
elog(ERROR, "amreplace: failed ReadBuffer");
}
#endif /* NO_BUFFERISVALID */
dp = (Page) BufferGetPage(buffer);
lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(otid));
@ -1302,8 +1299,9 @@ heap_replace(Relation relation, ItemPointer otid, HeapTuple replace_tuple)
* ----------------
*/
old_tuple = (HeapTuple) PageGetItem(dp, lp);
Assert(HeapTupleIsValid(old_tuple));
oldtup.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
oldtup.t_len = ItemIdGetLength(lp);
oldtup.t_self = *otid;
/* -----------------
* the following test should be able to catch all non-functional
@ -1316,7 +1314,7 @@ heap_replace(Relation relation, ItemPointer otid, HeapTuple replace_tuple)
* -----------------
*/
if (TupleUpdatedByCurXactAndCmd(old_tuple))
if (TupleUpdatedByCurXactAndCmd(&oldtup))
{
elog(NOTICE, "Non-functional update, only first update is performed");
if (IsSystemRelationName(RelationGetRelationName(relation)->data))
@ -1335,34 +1333,33 @@ heap_replace(Relation relation, ItemPointer otid, HeapTuple replace_tuple)
* xact, we only want to flag the 'non-functional' NOTICE. -mer
* ----------------
*/
HeapTupleSatisfies(lp,
HeapTupleSatisfies((&oldtup),
relation,
buffer,
(PageHeader) dp,
false,
0,
(ScanKey) NULL,
tuple);
if (!tuple)
(ScanKey) NULL);
if (!(oldtup.t_data))
{
ReleaseBuffer(buffer);
elog(ERROR, "heap_replace: (am)invalid otid");
}
/* XXX order problems if not atomic assignment ??? */
replace_tuple->t_oid = old_tuple->t_oid;
TransactionIdStore(GetCurrentTransactionId(), &(replace_tuple->t_xmin));
replace_tuple->t_cmin = GetCurrentCommandId();
StoreInvalidTransactionId(&(replace_tuple->t_xmax));
replace_tuple->t_infomask &= ~(HEAP_XACT_MASK);
replace_tuple->t_infomask |= HEAP_XMAX_INVALID;
newtup->t_data->t_oid = oldtup.t_data->t_oid;
TransactionIdStore(GetCurrentTransactionId(), &(newtup->t_data->t_xmin));
newtup->t_data->t_cmin = GetCurrentCommandId();
StoreInvalidTransactionId(&(newtup->t_data->t_xmax));
newtup->t_data->t_infomask &= ~(HEAP_XACT_MASK);
newtup->t_data->t_infomask |= HEAP_XMAX_INVALID;
/* ----------------
* insert new item
* ----------------
*/
if ((unsigned) DOUBLEALIGN(replace_tuple->t_len) <= PageGetFreeSpace((Page) dp))
RelationPutHeapTuple(relation, BufferGetBlockNumber(buffer), replace_tuple);
if ((unsigned) DOUBLEALIGN(newtup->t_len) <= PageGetFreeSpace((Page) dp))
RelationPutHeapTuple(relation, BufferGetBlockNumber(buffer), newtup);
else
{
/* ----------------
@ -1370,22 +1367,22 @@ heap_replace(Relation relation, ItemPointer otid, HeapTuple replace_tuple)
* for a new place to put it.
* ----------------
*/
doinsert(relation, replace_tuple);
doinsert(relation, newtup);
}
/* ----------------
* new item in place, now record transaction information
* ----------------
*/
TransactionIdStore(GetCurrentTransactionId(), &(old_tuple->t_xmax));
old_tuple->t_cmax = GetCurrentCommandId();
old_tuple->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_XMAX_INVALID);
TransactionIdStore(GetCurrentTransactionId(), &(oldtup.t_data->t_xmax));
oldtup.t_data->t_cmax = GetCurrentCommandId();
oldtup.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_XMAX_INVALID);
/* ----------------
* invalidate caches
* ----------------
*/
RelationInvalidateHeapTuple(relation, old_tuple);
RelationInvalidateHeapTuple(relation, &oldtup);
WriteBuffer(buffer);
@ -1423,48 +1420,46 @@ heap_markpos(HeapScanDesc scan)
/* Note: no locking manipulations needed */
if (scan->rs_ptup == NULL &&
if (scan->rs_ptup.t_data == NULL &&
BufferIsUnknown(scan->rs_pbuf))
{ /* == NONTUP */
scan->rs_ptup = (HeapTuple)
heapgettup(scan->rs_rd,
(scan->rs_ctup == NULL) ?
(ItemPointer) NULL : &scan->rs_ctup->t_ctid,
-1,
&scan->rs_pbuf,
scan->rs_snapshot,
scan->rs_nkeys,
scan->rs_key);
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 == NULL &&
else if (scan->rs_ntup.t_data == NULL &&
BufferIsUnknown(scan->rs_nbuf))
{ /* == NONTUP */
scan->rs_ntup = (HeapTuple)
heapgettup(scan->rs_rd,
(scan->rs_ctup == NULL) ?
(ItemPointer) NULL : &scan->rs_ctup->t_ctid,
1,
&scan->rs_nbuf,
scan->rs_snapshot,
scan->rs_nkeys,
scan->rs_key);
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 != NULL)
scan->rs_mptid = scan->rs_ptup->t_ctid;
if (scan->rs_ptup.t_data != NULL)
scan->rs_mptid = scan->rs_ptup.t_self;
else
ItemPointerSetInvalid(&scan->rs_mptid);
if (scan->rs_ctup != NULL)
scan->rs_mctid = scan->rs_ctup->t_ctid;
if (scan->rs_ctup.t_data != NULL)
scan->rs_mctid = scan->rs_ctup.t_self;
else
ItemPointerSetInvalid(&scan->rs_mctid);
if (scan->rs_ntup != NULL)
scan->rs_mntid = scan->rs_ntup->t_ctid;
if (scan->rs_ntup.t_data != NULL)
scan->rs_mntid = scan->rs_ntup.t_self;
else
ItemPointerSetInvalid(&scan->rs_mntid);
}
@ -1512,44 +1507,47 @@ heap_restrpos(HeapScanDesc scan)
scan->rs_nbuf = InvalidBuffer;
if (!ItemPointerIsValid(&scan->rs_mptid))
scan->rs_ptup = NULL;
scan->rs_ptup.t_data = NULL;
else
{
scan->rs_ptup = (HeapTuple)
heapgettup(scan->rs_rd,
&scan->rs_mptid,
0,
&scan->rs_pbuf,
false,
0,
(ScanKey) NULL);
scan->rs_ptup.t_self = scan->rs_mptid;
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))
scan->rs_ctup = NULL;
scan->rs_ctup.t_data = NULL;
else
{
scan->rs_ctup = (HeapTuple)
heapgettup(scan->rs_rd,
&scan->rs_mctid,
0,
&scan->rs_cbuf,
false,
0,
(ScanKey) NULL);
scan->rs_ctup.t_self = scan->rs_mctid;
scan->rs_ctup.t_data = (HeapTupleHeader) 0x1; /* for heapgettup */
heapgettup(scan->rs_rd,
&(scan->rs_ctup),
0,
&(scan->rs_cbuf),
false,
0,
(ScanKey) NULL);
}
if (!ItemPointerIsValid(&scan->rs_mntid))
scan->rs_ntup = NULL;
scan->rs_ntup.t_data = NULL;
else
{
scan->rs_ntup = (HeapTuple)
heapgettup(scan->rs_rd,
&scan->rs_mntid,
0,
&scan->rs_nbuf,
false,
0,
(ScanKey) 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,
0,
(ScanKey) NULL);
}
}

View File

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Id: hio.c,v 1.13 1998/01/07 21:01:23 momjian Exp $
* $Id: hio.c,v 1.14 1998/11/27 19:51:36 vadim Exp $
*
*-------------------------------------------------------------------------
*/
@ -69,17 +69,17 @@ RelationPutHeapTuple(Relation relation,
len = (unsigned) DOUBLEALIGN(tuple->t_len); /* be conservative */
Assert((int) len <= PageGetFreeSpace(pageHeader));
offnum = PageAddItem((Page) pageHeader, (Item) tuple,
offnum = PageAddItem((Page) pageHeader, (Item) tuple->t_data,
tuple->t_len, InvalidOffsetNumber, LP_USED);
itemId = PageGetItemId((Page) pageHeader, offnum);
item = PageGetItem((Page) pageHeader, itemId);
ItemPointerSet(&((HeapTuple) item)->t_ctid, blockIndex, offnum);
ItemPointerSet(&((HeapTupleHeader) item)->t_ctid, blockIndex, offnum);
WriteBuffer(buffer);
/* return an accurate tuple */
ItemPointerSet(&tuple->t_ctid, blockIndex, offnum);
ItemPointerSet(&tuple->t_self, blockIndex, offnum);
}
/*
@ -160,7 +160,7 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
elog(ERROR, "Tuple is too big: size %d", len);
}
offnum = PageAddItem((Page) pageHeader, (Item) tuple,
offnum = PageAddItem((Page) pageHeader, (Item) tuple->t_data,
tuple->t_len, InvalidOffsetNumber, LP_USED);
itemId = PageGetItemId((Page) pageHeader, offnum);
@ -168,10 +168,10 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
lastblock = BufferGetBlockNumber(buffer);
ItemPointerSet(&((HeapTuple) item)->t_ctid, lastblock, offnum);
ItemPointerSet(&((HeapTupleHeader) item)->t_ctid, lastblock, offnum);
/* return an accurate tuple */
ItemPointerSet(&tuple->t_ctid, lastblock, offnum);
ItemPointerSet(&tuple->t_self, lastblock, offnum);
WriteBuffer(buffer);
}