mirror of
https://github.com/postgres/postgres.git
synced 2025-08-27 07:42:10 +03:00
New HeapTuple structure/interface.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.45 1998/10/08 18:29:10 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.46 1998/11/27 19:51:27 vadim Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The old interface functions have been converted to macros
|
||||
@@ -36,12 +36,12 @@
|
||||
/* Used by heap_getattr() macro, for speed */
|
||||
long heap_sysoffset[] = {
|
||||
/* Only the first one is pass-by-ref, and is handled specially in the macro */
|
||||
offsetof(HeapTupleData, t_ctid),
|
||||
offsetof(HeapTupleData, t_oid),
|
||||
offsetof(HeapTupleData, t_xmin),
|
||||
offsetof(HeapTupleData, t_cmin),
|
||||
offsetof(HeapTupleData, t_xmax),
|
||||
offsetof(HeapTupleData, t_cmax)
|
||||
offsetof(HeapTupleHeaderData, t_ctid),
|
||||
offsetof(HeapTupleHeaderData, t_oid),
|
||||
offsetof(HeapTupleHeaderData, t_xmin),
|
||||
offsetof(HeapTupleHeaderData, t_cmin),
|
||||
offsetof(HeapTupleHeaderData, t_xmax),
|
||||
offsetof(HeapTupleHeaderData, t_cmax)
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
@@ -167,14 +167,14 @@ DataFill(char *data,
|
||||
int
|
||||
heap_attisnull(HeapTuple tup, int attnum)
|
||||
{
|
||||
if (attnum > (int) tup->t_natts)
|
||||
if (attnum > (int) tup->t_data->t_natts)
|
||||
return 1;
|
||||
|
||||
if (HeapTupleNoNulls(tup))
|
||||
return 0;
|
||||
|
||||
if (attnum > 0)
|
||||
return att_isnull(attnum - 1, tup->t_bits);
|
||||
return att_isnull(attnum - 1, tup->t_data->t_bits);
|
||||
else
|
||||
switch (attnum)
|
||||
{
|
||||
@@ -210,7 +210,7 @@ heap_attisnull(HeapTuple tup, int attnum)
|
||||
int
|
||||
heap_sysattrlen(AttrNumber attno)
|
||||
{
|
||||
HeapTupleData *f = NULL;
|
||||
HeapTupleHeader f = NULL;
|
||||
|
||||
switch (attno)
|
||||
{
|
||||
@@ -323,15 +323,16 @@ heap_getsysattr(HeapTuple tup, Buffer b, int attnum)
|
||||
* ----------------
|
||||
*/
|
||||
Datum
|
||||
nocachegetattr(HeapTuple tup,
|
||||
nocachegetattr(HeapTuple tuple,
|
||||
int attnum,
|
||||
TupleDesc tupleDesc,
|
||||
bool *isnull)
|
||||
{
|
||||
char *tp; /* ptr to att in tuple */
|
||||
bits8 *bp = tup->t_bits; /* ptr to att in tuple */
|
||||
int slow; /* do we have to walk nulls? */
|
||||
Form_pg_attribute *att = tupleDesc->attrs;
|
||||
char *tp; /* ptr to att in tuple */
|
||||
HeapTupleHeader tup = tuple->t_data;
|
||||
bits8 *bp = tup->t_bits; /* ptr to att in tuple */
|
||||
int slow; /* do we have to walk nulls? */
|
||||
Form_pg_attribute *att = tupleDesc->attrs;
|
||||
|
||||
|
||||
#if IN_MACRO
|
||||
@@ -351,7 +352,7 @@ nocachegetattr(HeapTuple tup,
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
if (HeapTupleNoNulls(tup))
|
||||
if (HeapTupleNoNulls(tuple))
|
||||
{
|
||||
attnum--;
|
||||
|
||||
@@ -449,7 +450,7 @@ nocachegetattr(HeapTuple tup,
|
||||
}
|
||||
else if (attnum == 0)
|
||||
return (Datum) fetchatt(&(att[0]), (char *) tp);
|
||||
else if (!HeapTupleAllFixed(tup))
|
||||
else if (!HeapTupleAllFixed(tuple))
|
||||
{
|
||||
int j = 0;
|
||||
|
||||
@@ -491,8 +492,8 @@ nocachegetattr(HeapTuple tup,
|
||||
/* Can we compute more? We will probably need them */
|
||||
(j < tup->t_natts &&
|
||||
att[j]->attcacheoff == -1 &&
|
||||
(HeapTupleNoNulls(tup) || !att_isnull(j, bp)) &&
|
||||
(HeapTupleAllFixed(tup) ||
|
||||
(HeapTupleNoNulls(tuple) || !att_isnull(j, bp)) &&
|
||||
(HeapTupleAllFixed(tuple) ||
|
||||
att[j]->attlen > 0 || VARLENA_FIXED_SIZE(att[j]))); j++)
|
||||
{
|
||||
|
||||
@@ -527,7 +528,7 @@ nocachegetattr(HeapTuple tup,
|
||||
|
||||
for (i = 0; i < attnum; i++)
|
||||
{
|
||||
if (!HeapTupleNoNulls(tup))
|
||||
if (!HeapTupleNoNulls(tuple))
|
||||
{
|
||||
if (att_isnull(i, bp))
|
||||
{
|
||||
@@ -570,14 +571,41 @@ heap_copytuple(HeapTuple tuple)
|
||||
{
|
||||
HeapTuple newTuple;
|
||||
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
if (!HeapTupleIsValid(tuple) || tuple->t_data == NULL)
|
||||
return NULL;
|
||||
|
||||
newTuple = (HeapTuple) palloc(tuple->t_len);
|
||||
memmove((char *) newTuple, (char *) tuple, (int) tuple->t_len);
|
||||
newTuple = (HeapTuple) palloc(HEAPTUPLESIZE + tuple->t_len);
|
||||
newTuple->t_len = tuple->t_len;
|
||||
newTuple->t_self = tuple->t_self;
|
||||
newTuple->t_data = (HeapTupleHeader) ((char *) newTuple + HEAPTUPLESIZE);
|
||||
memmove((char *) newTuple->t_data,
|
||||
(char *) tuple->t_data, (int) tuple->t_len);
|
||||
return newTuple;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* heap_copytuple_with_tuple
|
||||
*
|
||||
* returns a copy of an tuple->t_data
|
||||
* ----------------
|
||||
*/
|
||||
void
|
||||
heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest)
|
||||
{
|
||||
if (!HeapTupleIsValid(src) || src->t_data == NULL)
|
||||
{
|
||||
dest->t_data = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
dest->t_len = src->t_len;
|
||||
dest->t_self = src->t_self;
|
||||
dest->t_data = (HeapTupleHeader) palloc(src->t_len);
|
||||
memmove((char *) dest->t_data,
|
||||
(char *) src->t_data, (int) src->t_len);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef NOT_USED
|
||||
/* ----------------
|
||||
* heap_deformtuple
|
||||
@@ -637,16 +665,16 @@ heap_formtuple(TupleDesc tupleDescriptor,
|
||||
Datum *value,
|
||||
char *nulls)
|
||||
{
|
||||
char *tp; /* tuple pointer */
|
||||
HeapTuple tuple; /* return tuple */
|
||||
int bitmaplen;
|
||||
long len;
|
||||
int hoff;
|
||||
bool hasnull = false;
|
||||
int i;
|
||||
int numberOfAttributes = tupleDescriptor->natts;
|
||||
HeapTuple tuple; /* return tuple */
|
||||
HeapTupleHeader td; /* tuple data */
|
||||
int bitmaplen;
|
||||
long len;
|
||||
int hoff;
|
||||
bool hasnull = false;
|
||||
int i;
|
||||
int numberOfAttributes = tupleDescriptor->natts;
|
||||
|
||||
len = offsetof(HeapTupleData, t_bits);
|
||||
len = offsetof(HeapTupleHeaderData, t_bits);
|
||||
|
||||
for (i = 0; i < numberOfAttributes && !hasnull; i++)
|
||||
{
|
||||
@@ -668,23 +696,24 @@ heap_formtuple(TupleDesc tupleDescriptor,
|
||||
|
||||
len += ComputeDataSize(tupleDescriptor, value, nulls);
|
||||
|
||||
tp = (char *) palloc(len);
|
||||
tuple = (HeapTuple) tp;
|
||||
tuple = (HeapTuple) palloc(HEAPTUPLESIZE + len);
|
||||
td = tuple->t_data = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);;
|
||||
|
||||
MemSet(tp, 0, (int) len);
|
||||
MemSet((char *) td, 0, (int) len);
|
||||
|
||||
tuple->t_len = len;
|
||||
tuple->t_natts = numberOfAttributes;
|
||||
tuple->t_hoff = hoff;
|
||||
ItemPointerSetInvalid(&(tuple->t_self));
|
||||
td->t_natts = numberOfAttributes;
|
||||
td->t_hoff = hoff;
|
||||
|
||||
DataFill((char *) tuple + tuple->t_hoff,
|
||||
DataFill((char *) td + td->t_hoff,
|
||||
tupleDescriptor,
|
||||
value,
|
||||
nulls,
|
||||
&tuple->t_infomask,
|
||||
(hasnull ? tuple->t_bits : NULL));
|
||||
&td->t_infomask,
|
||||
(hasnull ? td->t_bits : NULL));
|
||||
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
td->t_infomask |= HEAP_XMAX_INVALID;
|
||||
|
||||
return tuple;
|
||||
}
|
||||
@@ -767,13 +796,15 @@ heap_modifytuple(HeapTuple tuple,
|
||||
* copy the header except for t_len, t_natts, t_hoff, t_bits, t_infomask
|
||||
* ----------------
|
||||
*/
|
||||
infomask = newTuple->t_infomask;
|
||||
memmove((char *) &newTuple->t_oid, /* XXX */
|
||||
(char *) &tuple->t_oid,
|
||||
((char *) &tuple->t_hoff - (char *) &tuple->t_oid)); /* XXX */
|
||||
newTuple->t_infomask = infomask;
|
||||
newTuple->t_natts = numberOfAttributes; /* fix t_natts just in
|
||||
* case */
|
||||
infomask = newTuple->t_data->t_infomask;
|
||||
memmove((char *) &newTuple->t_data->t_oid, /* XXX */
|
||||
(char *) &tuple->t_data->t_oid,
|
||||
((char *) &tuple->t_data->t_hoff -
|
||||
(char *) &tuple->t_data->t_oid)); /* XXX */
|
||||
newTuple->t_data->t_infomask = infomask;
|
||||
newTuple->t_data->t_natts = numberOfAttributes;
|
||||
newTuple->t_self = tuple->t_self;
|
||||
|
||||
return newTuple;
|
||||
}
|
||||
|
||||
@@ -787,28 +818,30 @@ heap_addheader(uint32 natts, /* max domain index */
|
||||
int structlen, /* its length */
|
||||
char *structure) /* pointer to the struct */
|
||||
{
|
||||
char *tp; /* tuple data pointer */
|
||||
HeapTuple tup;
|
||||
long len;
|
||||
int hoff;
|
||||
HeapTuple tuple;
|
||||
HeapTupleHeader td; /* tuple data */
|
||||
long len;
|
||||
int hoff;
|
||||
|
||||
AssertArg(natts > 0);
|
||||
|
||||
len = offsetof(HeapTupleData, t_bits);
|
||||
len = offsetof(HeapTupleHeaderData, t_bits);
|
||||
|
||||
hoff = len = DOUBLEALIGN(len); /* be conservative */
|
||||
len += structlen;
|
||||
tp = (char *) palloc(len);
|
||||
tup = (HeapTuple) tp;
|
||||
MemSet((char *) tup, 0, len);
|
||||
tuple = (HeapTuple) palloc(HEAPTUPLESIZE + len);
|
||||
td = tuple->t_data = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
|
||||
|
||||
tup->t_len = len;
|
||||
tp += tup->t_hoff = hoff;
|
||||
tup->t_natts = natts;
|
||||
tup->t_infomask = 0;
|
||||
tup->t_infomask |= HEAP_XMAX_INVALID;
|
||||
MemSet((char *) td, 0, (int) len);
|
||||
|
||||
memmove(tp, structure, structlen);
|
||||
tuple->t_len = len;
|
||||
ItemPointerSetInvalid(&(tuple->t_self));
|
||||
td->t_hoff = hoff;
|
||||
td->t_natts = natts;
|
||||
td->t_infomask = 0;
|
||||
td->t_infomask |= HEAP_XMAX_INVALID;
|
||||
|
||||
return tup;
|
||||
memmove((char *) td + hoff, structure, structlen);
|
||||
|
||||
return tuple;
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/common/Attic/heapvalid.c,v 1.21 1997/09/22 03:58:32 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/common/Attic/heapvalid.c,v 1.22 1998/11/27 19:51:28 vadim Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -25,9 +25,9 @@
|
||||
bool
|
||||
TupleUpdatedByCurXactAndCmd(HeapTuple t)
|
||||
{
|
||||
if (TransactionIdEquals(t->t_xmax,
|
||||
if (TransactionIdEquals(t->t_data->t_xmax,
|
||||
GetCurrentTransactionId()) &&
|
||||
CommandIdGEScanCommandId(t->t_cmax))
|
||||
CommandIdGEScanCommandId(t->t_data->t_cmax))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.35 1998/09/01 04:26:40 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.36 1998/11/27 19:51:28 vadim Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -100,7 +100,7 @@ printtup(HeapTuple tuple, TupleDesc typeinfo)
|
||||
*/
|
||||
j = 0;
|
||||
k = 1 << 7;
|
||||
for (i = 0; i < tuple->t_natts;)
|
||||
for (i = 0; i < tuple->t_data->t_natts;)
|
||||
{
|
||||
i++; /* heap_getattr is a macro, so no
|
||||
* increment */
|
||||
@@ -122,7 +122,7 @@ printtup(HeapTuple tuple, TupleDesc typeinfo)
|
||||
* send the attributes of this tuple
|
||||
* ----------------
|
||||
*/
|
||||
for (i = 0; i < tuple->t_natts; ++i)
|
||||
for (i = 0; i < tuple->t_data->t_natts; ++i)
|
||||
{
|
||||
attr = heap_getattr(tuple, i + 1, typeinfo, &isnull);
|
||||
if (isnull)
|
||||
@@ -204,7 +204,7 @@ debugtup(HeapTuple tuple, TupleDesc typeinfo)
|
||||
bool isnull;
|
||||
Oid typoutput;
|
||||
|
||||
for (i = 0; i < tuple->t_natts; ++i)
|
||||
for (i = 0; i < tuple->t_data->t_natts; ++i)
|
||||
{
|
||||
attr = heap_getattr(tuple, i + 1, typeinfo, &isnull);
|
||||
typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
|
||||
@@ -251,7 +251,7 @@ printtup_internal(HeapTuple tuple, TupleDesc typeinfo)
|
||||
*/
|
||||
j = 0;
|
||||
k = 1 << 7;
|
||||
for (i = 0; i < tuple->t_natts;)
|
||||
for (i = 0; i < tuple->t_data->t_natts;)
|
||||
{
|
||||
i++; /* heap_getattr is a macro, so no
|
||||
* increment */
|
||||
@@ -274,9 +274,9 @@ printtup_internal(HeapTuple tuple, TupleDesc typeinfo)
|
||||
* ----------------
|
||||
*/
|
||||
#ifdef IPORTAL_DEBUG
|
||||
fprintf(stderr, "sending tuple with %d atts\n", tuple->t_natts);
|
||||
fprintf(stderr, "sending tuple with %d atts\n", tuple->t_data->t_natts);
|
||||
#endif
|
||||
for (i = 0; i < tuple->t_natts; ++i)
|
||||
for (i = 0; i < tuple->t_data->t_natts; ++i)
|
||||
{
|
||||
int32 len = typeinfo->attrs[i]->attlen;
|
||||
|
||||
|
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.44 1998/09/01 04:26:41 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.45 1998/11/27 19:51:28 vadim Exp $
|
||||
*
|
||||
* NOTES
|
||||
* some of the executor utility code such as "ExecTypeFromTL" should be
|
||||
@@ -351,7 +351,7 @@ TupleDescInitEntry(TupleDesc desc,
|
||||
*/
|
||||
typeForm = (Form_pg_type) GETSTRUCT(tuple);
|
||||
|
||||
att->atttypid = tuple->t_oid;
|
||||
att->atttypid = tuple->t_data->t_oid;
|
||||
att->attalign = typeForm->typalign;
|
||||
|
||||
/* ------------------------
|
||||
|
@@ -248,7 +248,7 @@ gistbuild(Relation heap,
|
||||
|
||||
/* form an index tuple and point it at the heap tuple */
|
||||
itup = index_formtuple(id, &d[0], nulls);
|
||||
itup->t_tid = htup->t_ctid;
|
||||
itup->t_tid = htup->t_self;
|
||||
|
||||
/*
|
||||
* Since we already have the index relation locked, we call
|
||||
|
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.22 1998/09/01 04:26:48 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.23 1998/11/27 19:51:31 vadim Exp $
|
||||
*
|
||||
* NOTES
|
||||
* This file contains only the public interface routines.
|
||||
@@ -216,7 +216,7 @@ hashbuild(Relation heap,
|
||||
continue;
|
||||
}
|
||||
|
||||
itup->t_tid = htup->t_ctid;
|
||||
itup->t_tid = htup->t_self;
|
||||
hitem = _hash_formitem(itup);
|
||||
res = _hash_doinsert(index, hitem);
|
||||
pfree(hitem);
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.30 1998/09/01 04:27:01 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.31 1998/11/27 19:51:40 vadim Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -96,13 +96,12 @@ _bt_doinsert(Relation rel, BTItem btitem, bool index_is_unique, Relation heapRel
|
||||
/* key on the page before trying to compare it */
|
||||
if (!PageIsEmpty(page) && offset <= maxoff)
|
||||
{
|
||||
TupleDesc itupdesc;
|
||||
BTItem btitem;
|
||||
IndexTuple itup;
|
||||
HeapTuple htup;
|
||||
BTPageOpaque opaque;
|
||||
Buffer nbuf;
|
||||
BlockNumber blkno;
|
||||
TupleDesc itupdesc;
|
||||
BTItem btitem;
|
||||
HeapTupleData htup;
|
||||
BTPageOpaque opaque;
|
||||
Buffer nbuf;
|
||||
BlockNumber blkno;
|
||||
|
||||
itupdesc = RelationGetDescr(rel);
|
||||
nbuf = InvalidBuffer;
|
||||
@@ -120,9 +119,9 @@ _bt_doinsert(Relation rel, BTItem btitem, bool index_is_unique, Relation heapRel
|
||||
while (_bt_isequal(itupdesc, page, offset, natts, itup_scankey))
|
||||
{ /* they're equal */
|
||||
btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offset));
|
||||
itup = &(btitem->bti_itup);
|
||||
htup = heap_fetch(heapRel, SnapshotSelf, &(itup->t_tid), &buffer);
|
||||
if (htup != (HeapTuple) NULL)
|
||||
htup.t_self = btitem->bti_itup.t_tid;
|
||||
heap_fetch(heapRel, SnapshotSelf, &htup, &buffer);
|
||||
if (htup.t_data != NULL)
|
||||
{ /* it is a duplicate */
|
||||
elog(ERROR, "Cannot insert a duplicate key into a unique index");
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.33 1998/09/07 05:35:33 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.34 1998/11/27 19:51:40 vadim Exp $
|
||||
*
|
||||
* NOTES
|
||||
* This file contains only the public interface routines.
|
||||
@@ -256,7 +256,7 @@ btbuild(Relation heap,
|
||||
* if (itup->t_info & INDEX_NULL_MASK) { pfree(itup); continue; }
|
||||
*/
|
||||
|
||||
itup->t_tid = htup->t_ctid;
|
||||
itup->t_tid = htup->t_self;
|
||||
btitem = _bt_formitem(itup);
|
||||
|
||||
/*
|
||||
|
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.28 1998/09/01 04:27:10 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.29 1998/11/27 19:51:41 vadim Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -233,7 +233,7 @@ rtbuild(Relation heap,
|
||||
|
||||
/* form an index tuple and point it at the heap tuple */
|
||||
itup = index_formtuple(id, &d[0], nulls);
|
||||
itup->t_tid = htup->t_ctid;
|
||||
itup->t_tid = htup->t_self;
|
||||
|
||||
/*
|
||||
* Since we already have the index relation locked, we call
|
||||
|
Reference in New Issue
Block a user