mirror of
https://github.com/postgres/postgres.git
synced 2025-07-23 03:21:12 +03:00
pgindent run. Make it all clean.
This commit is contained in:
@ -8,14 +8,14 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.110 2001/01/24 19:42:47 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.111 2001/03/22 03:59:13 momjian 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
|
||||
* heap_open[r]_nofail - same, but return NULL on failure instead of elog
|
||||
* heap_close - close a heap relation
|
||||
* heap_beginscan - begin relation scan
|
||||
* heap_rescan - restart a relation scan
|
||||
@ -88,16 +88,16 @@
|
||||
|
||||
#include "access/xlogutils.h"
|
||||
|
||||
XLogRecPtr log_heap_move(Relation reln, Buffer oldbuf, ItemPointerData from,
|
||||
Buffer newbuf, HeapTuple newtup);
|
||||
XLogRecPtr log_heap_clean(Relation reln, Buffer buffer,
|
||||
char *unused, int unlen);
|
||||
XLogRecPtr log_heap_move(Relation reln, Buffer oldbuf, ItemPointerData from,
|
||||
Buffer newbuf, HeapTuple newtup);
|
||||
XLogRecPtr log_heap_clean(Relation reln, Buffer buffer,
|
||||
char *unused, int unlen);
|
||||
|
||||
/* comments are in heap_update */
|
||||
static xl_heaptid _locked_tuple_;
|
||||
static xl_heaptid _locked_tuple_;
|
||||
static void _heap_unlock_tuple(void *data);
|
||||
static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf,
|
||||
ItemPointerData from, Buffer newbuf, HeapTuple newtup, bool move);
|
||||
static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf,
|
||||
ItemPointerData from, Buffer newbuf, HeapTuple newtup, bool move);
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
@ -249,7 +249,7 @@ heapgettup(Relation relation,
|
||||
OffsetNumber lineoff;
|
||||
int linesleft;
|
||||
ItemPointer tid = (tuple->t_data == NULL) ?
|
||||
(ItemPointer) NULL : &(tuple->t_self);
|
||||
(ItemPointer) NULL : &(tuple->t_self);
|
||||
|
||||
/* ----------------
|
||||
* increment access statistics
|
||||
@ -286,7 +286,7 @@ heapgettup(Relation relation,
|
||||
|
||||
if (!ItemPointerIsValid(tid))
|
||||
Assert(!PointerIsValid(tid));
|
||||
|
||||
|
||||
tuple->t_tableOid = relation->rd_id;
|
||||
|
||||
/* ----------------
|
||||
@ -538,9 +538,9 @@ fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
|
||||
(
|
||||
(tupleDesc)->attrs[(attnum) - 1]->attcacheoff >= 0 ?
|
||||
(
|
||||
fetchatt((tupleDesc)->attrs[(attnum) - 1],
|
||||
(char *) (tup)->t_data + (tup)->t_data->t_hoff +
|
||||
(tupleDesc)->attrs[(attnum) - 1]->attcacheoff)
|
||||
fetchatt((tupleDesc)->attrs[(attnum) - 1],
|
||||
(char *) (tup)->t_data + (tup)->t_data->t_hoff +
|
||||
(tupleDesc)->attrs[(attnum) - 1]->attcacheoff)
|
||||
)
|
||||
:
|
||||
nocachegetattr((tup), (attnum), (tupleDesc), (isnull))
|
||||
@ -564,7 +564,8 @@ fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
|
||||
)
|
||||
);
|
||||
}
|
||||
#endif /* defined(DISABLE_COMPLEX_MACRO)*/
|
||||
|
||||
#endif /* defined(DISABLE_COMPLEX_MACRO) */
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
@ -791,8 +792,8 @@ heap_beginscan(Relation relation,
|
||||
scan->rs_nkeys = (short) nkeys;
|
||||
|
||||
/*
|
||||
* we do this here instead of in initscan() because heap_rescan
|
||||
* also calls initscan() and we don't want to allocate memory again
|
||||
* we do this here instead of in initscan() because heap_rescan also
|
||||
* calls initscan() and we don't want to allocate memory again
|
||||
*/
|
||||
if (nkeys)
|
||||
scan->rs_key = (ScanKey) palloc(sizeof(ScanKeyData) * nkeys);
|
||||
@ -1316,7 +1317,7 @@ heap_get_latest_tid(Relation relation,
|
||||
Oid
|
||||
heap_insert(Relation relation, HeapTuple tup)
|
||||
{
|
||||
Buffer buffer;
|
||||
Buffer buffer;
|
||||
|
||||
/* increment access statistics */
|
||||
IncrHeapAccessStat(local_insert);
|
||||
@ -1350,7 +1351,7 @@ heap_insert(Relation relation, HeapTuple tup)
|
||||
* toasted attributes from some other relation, invoke the toaster.
|
||||
* ----------
|
||||
*/
|
||||
if (HeapTupleHasExtended(tup) ||
|
||||
if (HeapTupleHasExtended(tup) ||
|
||||
(MAXALIGN(tup->t_len) > TOAST_TUPLE_THRESHOLD))
|
||||
heap_tuple_toast_attrs(relation, tup, NULL);
|
||||
#endif
|
||||
@ -1364,17 +1365,17 @@ heap_insert(Relation relation, HeapTuple tup)
|
||||
|
||||
/* XLOG stuff */
|
||||
{
|
||||
xl_heap_insert xlrec;
|
||||
xl_heap_header xlhdr;
|
||||
XLogRecPtr recptr;
|
||||
XLogRecData rdata[3];
|
||||
Page page = BufferGetPage(buffer);
|
||||
uint8 info = XLOG_HEAP_INSERT;
|
||||
xl_heap_insert xlrec;
|
||||
xl_heap_header xlhdr;
|
||||
XLogRecPtr recptr;
|
||||
XLogRecData rdata[3];
|
||||
Page page = BufferGetPage(buffer);
|
||||
uint8 info = XLOG_HEAP_INSERT;
|
||||
|
||||
xlrec.target.node = relation->rd_node;
|
||||
xlrec.target.tid = tup->t_self;
|
||||
rdata[0].buffer = InvalidBuffer;
|
||||
rdata[0].data = (char*)&xlrec;
|
||||
rdata[0].data = (char *) &xlrec;
|
||||
rdata[0].len = SizeOfHeapInsert;
|
||||
rdata[0].next = &(rdata[1]);
|
||||
|
||||
@ -1383,12 +1384,12 @@ heap_insert(Relation relation, HeapTuple tup)
|
||||
xlhdr.t_hoff = tup->t_data->t_hoff;
|
||||
xlhdr.mask = tup->t_data->t_infomask;
|
||||
rdata[1].buffer = buffer;
|
||||
rdata[1].data = (char*)&xlhdr;
|
||||
rdata[1].data = (char *) &xlhdr;
|
||||
rdata[1].len = SizeOfHeapHeader;
|
||||
rdata[1].next = &(rdata[2]);
|
||||
|
||||
rdata[2].buffer = buffer;
|
||||
rdata[2].data = (char*) tup->t_data + offsetof(HeapTupleHeaderData, t_bits);
|
||||
rdata[2].data = (char *) tup->t_data + offsetof(HeapTupleHeaderData, t_bits);
|
||||
rdata[2].len = tup->t_len - offsetof(HeapTupleHeaderData, t_bits);
|
||||
rdata[2].next = NULL;
|
||||
|
||||
@ -1411,10 +1412,10 @@ heap_insert(Relation relation, HeapTuple tup)
|
||||
WriteBuffer(buffer);
|
||||
|
||||
/*
|
||||
* If tuple is cachable, mark it for rollback from the caches
|
||||
* in case we abort. Note it is OK to do this after WriteBuffer
|
||||
* releases the buffer, because the "tup" data structure is all
|
||||
* in local memory, not in the shared buffer.
|
||||
* If tuple is cachable, mark it for rollback from the caches in case
|
||||
* we abort. Note it is OK to do this after WriteBuffer releases the
|
||||
* buffer, because the "tup" data structure is all in local memory,
|
||||
* not in the shared buffer.
|
||||
*/
|
||||
RelationMark4RollbackHeapTuple(relation, tup);
|
||||
|
||||
@ -1513,14 +1514,14 @@ l1:
|
||||
HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
|
||||
/* XLOG stuff */
|
||||
{
|
||||
xl_heap_delete xlrec;
|
||||
XLogRecPtr recptr;
|
||||
XLogRecData rdata[2];
|
||||
xl_heap_delete xlrec;
|
||||
XLogRecPtr recptr;
|
||||
XLogRecData rdata[2];
|
||||
|
||||
xlrec.target.node = relation->rd_node;
|
||||
xlrec.target.tid = tp.t_self;
|
||||
rdata[0].buffer = InvalidBuffer;
|
||||
rdata[0].data = (char*)&xlrec;
|
||||
rdata[0].data = (char *) &xlrec;
|
||||
rdata[0].len = SizeOfHeapDelete;
|
||||
rdata[0].next = &(rdata[1]);
|
||||
|
||||
@ -1551,9 +1552,10 @@ l1:
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Mark tuple for invalidation from system caches at next command boundary.
|
||||
* We have to do this before WriteBuffer because we need to look at the
|
||||
* contents of the tuple, so we need to hold our refcount on the buffer.
|
||||
* Mark tuple for invalidation from system caches at next command
|
||||
* boundary. We have to do this before WriteBuffer because we need to
|
||||
* look at the contents of the tuple, so we need to hold our refcount
|
||||
* on the buffer.
|
||||
*/
|
||||
RelationInvalidateHeapTuple(relation, &tp);
|
||||
|
||||
@ -1567,7 +1569,7 @@ l1:
|
||||
*
|
||||
* This routine may be used to delete a tuple when concurrent updates of
|
||||
* the target tuple are not expected (for example, because we have a lock
|
||||
* on the relation associated with the tuple). Any failure is reported
|
||||
* on the relation associated with the tuple). Any failure is reported
|
||||
* via elog().
|
||||
*/
|
||||
void
|
||||
@ -1636,6 +1638,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
|
||||
oldtup.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
|
||||
oldtup.t_len = ItemIdGetLength(lp);
|
||||
oldtup.t_self = *otid;
|
||||
|
||||
/*
|
||||
* Note: beyond this point, use oldtup not otid to refer to old tuple.
|
||||
* otid may very well point at newtup->t_self, which we will overwrite
|
||||
@ -1701,23 +1704,24 @@ l2:
|
||||
|
||||
/*
|
||||
* If the toaster needs to be activated, OR if the new tuple will not
|
||||
* fit on the same page as the old, then we need to release the context
|
||||
* lock (but not the pin!) on the old tuple's buffer while we are off
|
||||
* doing TOAST and/or table-file-extension work. We must mark the old
|
||||
* tuple to show that it's already being updated, else other processes
|
||||
* may try to update it themselves. To avoid second XLOG log record,
|
||||
* we use xact mgr hook to unlock old tuple without reading log if xact
|
||||
* will abort before update is logged. In the event of crash prio logging,
|
||||
* TQUAL routines will see HEAP_XMAX_UNLOGGED flag...
|
||||
* fit on the same page as the old, then we need to release the
|
||||
* context lock (but not the pin!) on the old tuple's buffer while we
|
||||
* are off doing TOAST and/or table-file-extension work. We must mark
|
||||
* the old tuple to show that it's already being updated, else other
|
||||
* processes may try to update it themselves. To avoid second XLOG log
|
||||
* record, we use xact mgr hook to unlock old tuple without reading
|
||||
* log if xact will abort before update is logged. In the event of
|
||||
* crash prio logging, TQUAL routines will see HEAP_XMAX_UNLOGGED
|
||||
* flag...
|
||||
*
|
||||
* NOTE: this trick is useless currently but saved for future
|
||||
* when we'll implement UNDO and will re-use transaction IDs
|
||||
* after postmaster startup.
|
||||
* NOTE: this trick is useless currently but saved for future when we'll
|
||||
* implement UNDO and will re-use transaction IDs after postmaster
|
||||
* startup.
|
||||
*
|
||||
* We need to invoke the toaster if there are already any toasted values
|
||||
* present, or if the new tuple is over-threshold.
|
||||
*/
|
||||
need_toast = (HeapTupleHasExtended(&oldtup) ||
|
||||
need_toast = (HeapTupleHasExtended(&oldtup) ||
|
||||
HeapTupleHasExtended(newtup) ||
|
||||
(MAXALIGN(newtup->t_len) > TOAST_TUPLE_THRESHOLD));
|
||||
|
||||
@ -1726,7 +1730,7 @@ l2:
|
||||
{
|
||||
_locked_tuple_.node = relation->rd_node;
|
||||
_locked_tuple_.tid = oldtup.t_self;
|
||||
XactPushRollback(_heap_unlock_tuple, (void*) &_locked_tuple_);
|
||||
XactPushRollback(_heap_unlock_tuple, (void *) &_locked_tuple_);
|
||||
|
||||
TransactionIdStore(GetCurrentTransactionId(),
|
||||
&(oldtup.t_data->t_xmax));
|
||||
@ -1762,7 +1766,7 @@ l2:
|
||||
/* NO ELOG(ERROR) from here till changes are logged */
|
||||
START_CRIT_SECTION();
|
||||
|
||||
RelationPutHeapTuple(relation, newbuf, newtup); /* insert new tuple */
|
||||
RelationPutHeapTuple(relation, newbuf, newtup); /* insert new tuple */
|
||||
|
||||
if (already_marked)
|
||||
{
|
||||
@ -1784,7 +1788,7 @@ l2:
|
||||
|
||||
/* XLOG stuff */
|
||||
{
|
||||
XLogRecPtr recptr = log_heap_update(relation, buffer, oldtup.t_self,
|
||||
XLogRecPtr recptr = log_heap_update(relation, buffer, oldtup.t_self,
|
||||
newbuf, newtup, false);
|
||||
|
||||
if (newbuf != buffer)
|
||||
@ -1814,10 +1818,10 @@ l2:
|
||||
WriteBuffer(buffer);
|
||||
|
||||
/*
|
||||
* If new tuple is cachable, mark it for rollback from the caches
|
||||
* in case we abort. Note it is OK to do this after WriteBuffer
|
||||
* releases the buffer, because the "newtup" data structure is all
|
||||
* in local memory, not in the shared buffer.
|
||||
* If new tuple is cachable, mark it for rollback from the caches in
|
||||
* case we abort. Note it is OK to do this after WriteBuffer releases
|
||||
* the buffer, because the "newtup" data structure is all in local
|
||||
* memory, not in the shared buffer.
|
||||
*/
|
||||
RelationMark4RollbackHeapTuple(relation, newtup);
|
||||
|
||||
@ -1829,7 +1833,7 @@ l2:
|
||||
*
|
||||
* This routine may be used to update a tuple when concurrent updates of
|
||||
* the target tuple are not expected (for example, because we have a lock
|
||||
* on the relation associated with the tuple). Any failure is reported
|
||||
* on the relation associated with the tuple). Any failure is reported
|
||||
* via elog().
|
||||
*/
|
||||
void
|
||||
@ -2129,14 +2133,14 @@ heap_restrpos(HeapScanDesc scan)
|
||||
XLogRecPtr
|
||||
log_heap_clean(Relation reln, Buffer buffer, char *unused, int unlen)
|
||||
{
|
||||
xl_heap_clean xlrec;
|
||||
XLogRecPtr recptr;
|
||||
XLogRecData rdata[3];
|
||||
xl_heap_clean xlrec;
|
||||
XLogRecPtr recptr;
|
||||
XLogRecData rdata[3];
|
||||
|
||||
xlrec.node = reln->rd_node;
|
||||
xlrec.block = BufferGetBlockNumber(buffer);
|
||||
rdata[0].buffer = InvalidBuffer;
|
||||
rdata[0].data = (char*)&xlrec;
|
||||
rdata[0].data = (char *) &xlrec;
|
||||
rdata[0].len = SizeOfHeapClean;
|
||||
rdata[0].next = &(rdata[1]);
|
||||
|
||||
@ -2157,27 +2161,27 @@ log_heap_clean(Relation reln, Buffer buffer, char *unused, int unlen)
|
||||
|
||||
recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_CLEAN, rdata);
|
||||
|
||||
return(recptr);
|
||||
return (recptr);
|
||||
}
|
||||
|
||||
static XLogRecPtr
|
||||
log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from,
|
||||
log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from,
|
||||
Buffer newbuf, HeapTuple newtup, bool move)
|
||||
{
|
||||
char tbuf[MAXALIGN(sizeof(xl_heap_header)) + 2 * sizeof(TransactionId)];
|
||||
xl_heap_update xlrec;
|
||||
xl_heap_header *xlhdr = (xl_heap_header*) tbuf;
|
||||
int hsize = SizeOfHeapHeader;
|
||||
XLogRecPtr recptr;
|
||||
XLogRecData rdata[4];
|
||||
Page page = BufferGetPage(newbuf);
|
||||
uint8 info = (move) ? XLOG_HEAP_MOVE : XLOG_HEAP_UPDATE;
|
||||
char tbuf[MAXALIGN(sizeof(xl_heap_header)) + 2 * sizeof(TransactionId)];
|
||||
xl_heap_update xlrec;
|
||||
xl_heap_header *xlhdr = (xl_heap_header *) tbuf;
|
||||
int hsize = SizeOfHeapHeader;
|
||||
XLogRecPtr recptr;
|
||||
XLogRecData rdata[4];
|
||||
Page page = BufferGetPage(newbuf);
|
||||
uint8 info = (move) ? XLOG_HEAP_MOVE : XLOG_HEAP_UPDATE;
|
||||
|
||||
xlrec.target.node = reln->rd_node;
|
||||
xlrec.target.tid = from;
|
||||
xlrec.newtid = newtup->t_self;
|
||||
rdata[0].buffer = InvalidBuffer;
|
||||
rdata[0].data = (char*)&xlrec;
|
||||
rdata[0].data = (char *) &xlrec;
|
||||
rdata[0].len = SizeOfHeapUpdate;
|
||||
rdata[0].next = &(rdata[1]);
|
||||
|
||||
@ -2190,9 +2194,9 @@ log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from,
|
||||
xlhdr->t_natts = newtup->t_data->t_natts;
|
||||
xlhdr->t_hoff = newtup->t_data->t_hoff;
|
||||
xlhdr->mask = newtup->t_data->t_infomask;
|
||||
if (move) /* remember xmin & xmax */
|
||||
if (move) /* remember xmin & xmax */
|
||||
{
|
||||
TransactionId xmax;
|
||||
TransactionId xmax;
|
||||
|
||||
if (newtup->t_data->t_infomask & HEAP_XMAX_INVALID ||
|
||||
newtup->t_data->t_infomask & HEAP_MARKED_FOR_UPDATE)
|
||||
@ -2200,17 +2204,17 @@ log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from,
|
||||
else
|
||||
xmax = newtup->t_data->t_xmax;
|
||||
memcpy(tbuf + hsize, &xmax, sizeof(TransactionId));
|
||||
memcpy(tbuf + hsize + sizeof(TransactionId),
|
||||
&(newtup->t_data->t_xmin), sizeof(TransactionId));
|
||||
memcpy(tbuf + hsize + sizeof(TransactionId),
|
||||
&(newtup->t_data->t_xmin), sizeof(TransactionId));
|
||||
hsize += (2 * sizeof(TransactionId));
|
||||
}
|
||||
rdata[2].buffer = newbuf;
|
||||
rdata[2].data = (char*)xlhdr;
|
||||
rdata[2].data = (char *) xlhdr;
|
||||
rdata[2].len = hsize;
|
||||
rdata[2].next = &(rdata[3]);
|
||||
|
||||
rdata[3].buffer = newbuf;
|
||||
rdata[3].data = (char*) newtup->t_data + offsetof(HeapTupleHeaderData, t_bits);
|
||||
rdata[3].data = (char *) newtup->t_data + offsetof(HeapTupleHeaderData, t_bits);
|
||||
rdata[3].len = newtup->t_len - offsetof(HeapTupleHeaderData, t_bits);
|
||||
rdata[3].next = NULL;
|
||||
|
||||
@ -2224,23 +2228,23 @@ log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from,
|
||||
|
||||
recptr = XLogInsert(RM_HEAP_ID, info, rdata);
|
||||
|
||||
return(recptr);
|
||||
return (recptr);
|
||||
}
|
||||
|
||||
XLogRecPtr
|
||||
log_heap_move(Relation reln, Buffer oldbuf, ItemPointerData from,
|
||||
Buffer newbuf, HeapTuple newtup)
|
||||
log_heap_move(Relation reln, Buffer oldbuf, ItemPointerData from,
|
||||
Buffer newbuf, HeapTuple newtup)
|
||||
{
|
||||
return(log_heap_update(reln, oldbuf, from, newbuf, newtup, true));
|
||||
return (log_heap_update(reln, oldbuf, from, newbuf, newtup, true));
|
||||
}
|
||||
|
||||
static void
|
||||
heap_xlog_clean(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
||||
{
|
||||
xl_heap_clean *xlrec = (xl_heap_clean*) XLogRecGetData(record);
|
||||
Relation reln;
|
||||
Buffer buffer;
|
||||
Page page;
|
||||
xl_heap_clean *xlrec = (xl_heap_clean *) XLogRecGetData(record);
|
||||
Relation reln;
|
||||
Buffer buffer;
|
||||
Page page;
|
||||
|
||||
if (!redo || (record->xl_info & XLR_BKP_BLOCK_1))
|
||||
return;
|
||||
@ -2266,15 +2270,15 @@ heap_xlog_clean(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
||||
|
||||
if (record->xl_len > SizeOfHeapClean)
|
||||
{
|
||||
char unbuf[BLCKSZ];
|
||||
OffsetNumber *unused = (OffsetNumber*)unbuf;
|
||||
char *unend;
|
||||
ItemId lp;
|
||||
char unbuf[BLCKSZ];
|
||||
OffsetNumber *unused = (OffsetNumber *) unbuf;
|
||||
char *unend;
|
||||
ItemId lp;
|
||||
|
||||
memcpy(unbuf, (char*)xlrec + SizeOfHeapClean, record->xl_len - SizeOfHeapClean);
|
||||
memcpy(unbuf, (char *) xlrec + SizeOfHeapClean, record->xl_len - SizeOfHeapClean);
|
||||
unend = unbuf + (record->xl_len - SizeOfHeapClean);
|
||||
|
||||
while((char*)unused < unend)
|
||||
while ((char *) unused < unend)
|
||||
{
|
||||
lp = ((PageHeader) page)->pd_linp + *unused;
|
||||
lp->lp_flags &= ~LP_USED;
|
||||
@ -2289,13 +2293,13 @@ heap_xlog_clean(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
||||
static void
|
||||
heap_xlog_delete(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
||||
{
|
||||
xl_heap_delete *xlrec = (xl_heap_delete*) XLogRecGetData(record);
|
||||
Relation reln = XLogOpenRelation(redo, RM_HEAP_ID, xlrec->target.node);
|
||||
Buffer buffer;
|
||||
Page page;
|
||||
OffsetNumber offnum;
|
||||
ItemId lp = NULL;
|
||||
HeapTupleHeader htup;
|
||||
xl_heap_delete *xlrec = (xl_heap_delete *) XLogRecGetData(record);
|
||||
Relation reln = XLogOpenRelation(redo, RM_HEAP_ID, xlrec->target.node);
|
||||
Buffer buffer;
|
||||
Page page;
|
||||
OffsetNumber offnum;
|
||||
ItemId lp = NULL;
|
||||
HeapTupleHeader htup;
|
||||
|
||||
if (redo && (record->xl_info & XLR_BKP_BLOCK_1))
|
||||
return;
|
||||
@ -2303,7 +2307,7 @@ heap_xlog_delete(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
||||
if (!RelationIsValid(reln))
|
||||
return;
|
||||
|
||||
buffer = XLogReadBuffer(false, reln,
|
||||
buffer = XLogReadBuffer(false, reln,
|
||||
ItemPointerGetBlockNumber(&(xlrec->target.tid)));
|
||||
if (!BufferIsValid(buffer))
|
||||
elog(STOP, "heap_delete_%sdo: no block", (redo) ? "re" : "un");
|
||||
@ -2320,7 +2324,8 @@ heap_xlog_delete(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (XLByteLT(PageGetLSN(page), lsn)) /* changes are not applied ?! */
|
||||
else if (XLByteLT(PageGetLSN(page), lsn)) /* changes are not applied
|
||||
* ?! */
|
||||
elog(STOP, "heap_delete_undo: bad page LSN");
|
||||
|
||||
offnum = ItemPointerGetOffsetNumber(&(xlrec->target.tid));
|
||||
@ -2337,7 +2342,7 @@ heap_xlog_delete(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
||||
htup->t_xmax = record->xl_xid;
|
||||
htup->t_cmax = FirstCommandId;
|
||||
htup->t_infomask &= ~(HEAP_XMAX_COMMITTED |
|
||||
HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
|
||||
HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
|
||||
PageSetLSN(page, lsn);
|
||||
PageSetSUI(page, ThisStartUpID);
|
||||
UnlockAndWriteBuffer(buffer);
|
||||
@ -2350,12 +2355,12 @@ heap_xlog_delete(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
||||
static void
|
||||
heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
||||
{
|
||||
xl_heap_insert *xlrec = (xl_heap_insert*) XLogRecGetData(record);
|
||||
Relation reln = XLogOpenRelation(redo, RM_HEAP_ID, xlrec->target.node);
|
||||
Buffer buffer;
|
||||
Page page;
|
||||
OffsetNumber offnum;
|
||||
HeapTupleHeader htup;
|
||||
xl_heap_insert *xlrec = (xl_heap_insert *) XLogRecGetData(record);
|
||||
Relation reln = XLogOpenRelation(redo, RM_HEAP_ID, xlrec->target.node);
|
||||
Buffer buffer;
|
||||
Page page;
|
||||
OffsetNumber offnum;
|
||||
HeapTupleHeader htup;
|
||||
|
||||
if (redo && (record->xl_info & XLR_BKP_BLOCK_1))
|
||||
return;
|
||||
@ -2363,7 +2368,7 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
||||
if (!RelationIsValid(reln))
|
||||
return;
|
||||
|
||||
buffer = XLogReadBuffer((redo) ? true : false, reln,
|
||||
buffer = XLogReadBuffer((redo) ? true : false, reln,
|
||||
ItemPointerGetBlockNumber(&(xlrec->target.tid)));
|
||||
if (!BufferIsValid(buffer))
|
||||
return;
|
||||
@ -2375,9 +2380,9 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
||||
|
||||
if (redo)
|
||||
{
|
||||
char tbuf[MaxTupleSize];
|
||||
xl_heap_header xlhdr;
|
||||
uint32 newlen;
|
||||
char tbuf[MaxTupleSize];
|
||||
xl_heap_header xlhdr;
|
||||
uint32 newlen;
|
||||
|
||||
if (record->xl_info & XLOG_HEAP_INIT_PAGE)
|
||||
{
|
||||
@ -2396,9 +2401,9 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
||||
elog(STOP, "heap_insert_redo: invalid max offset number");
|
||||
|
||||
newlen = record->xl_len - SizeOfHeapInsert - SizeOfHeapHeader;
|
||||
memcpy((char*)&xlhdr, (char*)xlrec + SizeOfHeapInsert, SizeOfHeapHeader);
|
||||
memcpy(tbuf + offsetof(HeapTupleHeaderData, t_bits),
|
||||
(char*)xlrec + SizeOfHeapInsert + SizeOfHeapHeader, newlen);
|
||||
memcpy((char *) &xlhdr, (char *) xlrec + SizeOfHeapInsert, SizeOfHeapHeader);
|
||||
memcpy(tbuf + offsetof(HeapTupleHeaderData, t_bits),
|
||||
(char *) xlrec + SizeOfHeapInsert + SizeOfHeapHeader, newlen);
|
||||
newlen += offsetof(HeapTupleHeaderData, t_bits);
|
||||
htup = (HeapTupleHeader) tbuf;
|
||||
htup->t_oid = xlhdr.t_oid;
|
||||
@ -2408,19 +2413,20 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
||||
htup->t_cmin = FirstCommandId;
|
||||
htup->t_xmax = htup->t_cmax = 0;
|
||||
htup->t_infomask = HEAP_XMAX_INVALID | xlhdr.mask;
|
||||
|
||||
offnum = PageAddItem(page, (Item)htup, newlen, offnum,
|
||||
LP_USED | OverwritePageMode);
|
||||
|
||||
offnum = PageAddItem(page, (Item) htup, newlen, offnum,
|
||||
LP_USED | OverwritePageMode);
|
||||
if (offnum == InvalidOffsetNumber)
|
||||
elog(STOP, "heap_insert_redo: failed to add tuple");
|
||||
PageSetLSN(page, lsn);
|
||||
PageSetSUI(page, ThisStartUpID); /* prev sui */
|
||||
PageSetSUI(page, ThisStartUpID); /* prev sui */
|
||||
UnlockAndWriteBuffer(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
/* undo insert */
|
||||
if (XLByteLT(PageGetLSN(page), lsn)) /* changes are not applied ?! */
|
||||
if (XLByteLT(PageGetLSN(page), lsn)) /* changes are not applied
|
||||
* ?! */
|
||||
elog(STOP, "heap_insert_undo: bad page LSN");
|
||||
|
||||
elog(STOP, "heap_insert_undo: unimplemented");
|
||||
@ -2432,16 +2438,16 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
||||
static void
|
||||
heap_xlog_update(bool redo, XLogRecPtr lsn, XLogRecord *record, bool move)
|
||||
{
|
||||
xl_heap_update *xlrec = (xl_heap_update*) XLogRecGetData(record);
|
||||
Relation reln = XLogOpenRelation(redo, RM_HEAP_ID, xlrec->target.node);
|
||||
Buffer buffer;
|
||||
bool samepage =
|
||||
(ItemPointerGetBlockNumber(&(xlrec->newtid)) ==
|
||||
ItemPointerGetBlockNumber(&(xlrec->target.tid)));
|
||||
Page page;
|
||||
OffsetNumber offnum;
|
||||
ItemId lp = NULL;
|
||||
HeapTupleHeader htup;
|
||||
xl_heap_update *xlrec = (xl_heap_update *) XLogRecGetData(record);
|
||||
Relation reln = XLogOpenRelation(redo, RM_HEAP_ID, xlrec->target.node);
|
||||
Buffer buffer;
|
||||
bool samepage =
|
||||
(ItemPointerGetBlockNumber(&(xlrec->newtid)) ==
|
||||
ItemPointerGetBlockNumber(&(xlrec->target.tid)));
|
||||
Page page;
|
||||
OffsetNumber offnum;
|
||||
ItemId lp = NULL;
|
||||
HeapTupleHeader htup;
|
||||
|
||||
if (!RelationIsValid(reln))
|
||||
return;
|
||||
@ -2451,7 +2457,7 @@ heap_xlog_update(bool redo, XLogRecPtr lsn, XLogRecord *record, bool move)
|
||||
|
||||
/* Deal with old tuple version */
|
||||
|
||||
buffer = XLogReadBuffer(false, reln,
|
||||
buffer = XLogReadBuffer(false, reln,
|
||||
ItemPointerGetBlockNumber(&(xlrec->target.tid)));
|
||||
if (!BufferIsValid(buffer))
|
||||
elog(STOP, "heap_update_%sdo: no block", (redo) ? "re" : "un");
|
||||
@ -2470,7 +2476,8 @@ heap_xlog_update(bool redo, XLogRecPtr lsn, XLogRecord *record, bool move)
|
||||
goto newt;
|
||||
}
|
||||
}
|
||||
else if (XLByteLT(PageGetLSN(page), lsn)) /* changes are not applied ?! */
|
||||
else if (XLByteLT(PageGetLSN(page), lsn)) /* changes are not applied
|
||||
* ?! */
|
||||
elog(STOP, "heap_update_undo: bad old tuple page LSN");
|
||||
|
||||
offnum = ItemPointerGetOffsetNumber(&(xlrec->target.tid));
|
||||
@ -2487,7 +2494,7 @@ heap_xlog_update(bool redo, XLogRecPtr lsn, XLogRecord *record, bool move)
|
||||
if (move)
|
||||
{
|
||||
TransactionIdStore(record->xl_xid, (TransactionId *) &(htup->t_cmin));
|
||||
htup->t_infomask &=
|
||||
htup->t_infomask &=
|
||||
~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_IN);
|
||||
htup->t_infomask |= HEAP_MOVED_OFF;
|
||||
}
|
||||
@ -2496,7 +2503,7 @@ heap_xlog_update(bool redo, XLogRecPtr lsn, XLogRecord *record, bool move)
|
||||
htup->t_xmax = record->xl_xid;
|
||||
htup->t_cmax = FirstCommandId;
|
||||
htup->t_infomask &= ~(HEAP_XMAX_COMMITTED |
|
||||
HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
|
||||
HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
|
||||
}
|
||||
if (samepage)
|
||||
goto newsame;
|
||||
@ -2514,11 +2521,11 @@ newt:;
|
||||
|
||||
if (redo &&
|
||||
((record->xl_info & XLR_BKP_BLOCK_2) ||
|
||||
((record->xl_info & XLR_BKP_BLOCK_1) && samepage)))
|
||||
((record->xl_info & XLR_BKP_BLOCK_1) && samepage)))
|
||||
return;
|
||||
|
||||
buffer = XLogReadBuffer((redo) ? true : false, reln,
|
||||
ItemPointerGetBlockNumber(&(xlrec->newtid)));
|
||||
buffer = XLogReadBuffer((redo) ? true : false, reln,
|
||||
ItemPointerGetBlockNumber(&(xlrec->newtid)));
|
||||
if (!BufferIsValid(buffer))
|
||||
return;
|
||||
|
||||
@ -2531,10 +2538,10 @@ newsame:;
|
||||
|
||||
if (redo)
|
||||
{
|
||||
char tbuf[MaxTupleSize];
|
||||
xl_heap_header xlhdr;
|
||||
int hsize;
|
||||
uint32 newlen;
|
||||
char tbuf[MaxTupleSize];
|
||||
xl_heap_header xlhdr;
|
||||
int hsize;
|
||||
uint32 newlen;
|
||||
|
||||
if (record->xl_info & XLOG_HEAP_INIT_PAGE)
|
||||
{
|
||||
@ -2557,9 +2564,9 @@ newsame:;
|
||||
hsize += (2 * sizeof(TransactionId));
|
||||
|
||||
newlen = record->xl_len - hsize;
|
||||
memcpy((char*)&xlhdr, (char*)xlrec + SizeOfHeapUpdate, SizeOfHeapHeader);
|
||||
memcpy(tbuf + offsetof(HeapTupleHeaderData, t_bits),
|
||||
(char*)xlrec + hsize, newlen);
|
||||
memcpy((char *) &xlhdr, (char *) xlrec + SizeOfHeapUpdate, SizeOfHeapHeader);
|
||||
memcpy(tbuf + offsetof(HeapTupleHeaderData, t_bits),
|
||||
(char *) xlrec + hsize, newlen);
|
||||
newlen += offsetof(HeapTupleHeaderData, t_bits);
|
||||
htup = (HeapTupleHeader) tbuf;
|
||||
htup->t_oid = xlhdr.t_oid;
|
||||
@ -2568,13 +2575,13 @@ newsame:;
|
||||
if (move)
|
||||
{
|
||||
hsize = SizeOfHeapUpdate + SizeOfHeapHeader;
|
||||
memcpy(&(htup->t_xmax), (char*)xlrec + hsize, sizeof(TransactionId));
|
||||
memcpy(&(htup->t_xmin),
|
||||
(char*)xlrec + hsize + sizeof(TransactionId), sizeof(TransactionId));
|
||||
memcpy(&(htup->t_xmax), (char *) xlrec + hsize, sizeof(TransactionId));
|
||||
memcpy(&(htup->t_xmin),
|
||||
(char *) xlrec + hsize + sizeof(TransactionId), sizeof(TransactionId));
|
||||
TransactionIdStore(record->xl_xid, (TransactionId *) &(htup->t_cmin));
|
||||
htup->t_infomask = xlhdr.mask;
|
||||
htup->t_infomask &= ~(HEAP_XMIN_COMMITTED |
|
||||
HEAP_XMIN_INVALID | HEAP_MOVED_OFF);
|
||||
htup->t_infomask &= ~(HEAP_XMIN_COMMITTED |
|
||||
HEAP_XMIN_INVALID | HEAP_MOVED_OFF);
|
||||
htup->t_infomask |= HEAP_MOVED_IN;
|
||||
}
|
||||
else
|
||||
@ -2584,19 +2591,20 @@ newsame:;
|
||||
htup->t_xmax = htup->t_cmax = 0;
|
||||
htup->t_infomask = HEAP_XMAX_INVALID | xlhdr.mask;
|
||||
}
|
||||
|
||||
offnum = PageAddItem(page, (Item)htup, newlen, offnum,
|
||||
LP_USED | OverwritePageMode);
|
||||
|
||||
offnum = PageAddItem(page, (Item) htup, newlen, offnum,
|
||||
LP_USED | OverwritePageMode);
|
||||
if (offnum == InvalidOffsetNumber)
|
||||
elog(STOP, "heap_update_redo: failed to add tuple");
|
||||
PageSetLSN(page, lsn);
|
||||
PageSetSUI(page, ThisStartUpID); /* prev sui */
|
||||
PageSetSUI(page, ThisStartUpID); /* prev sui */
|
||||
UnlockAndWriteBuffer(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
/* undo */
|
||||
if (XLByteLT(PageGetLSN(page), lsn)) /* changes are not applied ?! */
|
||||
if (XLByteLT(PageGetLSN(page), lsn)) /* changes are not applied
|
||||
* ?! */
|
||||
elog(STOP, "heap_update_undo: bad new tuple page LSN");
|
||||
|
||||
elog(STOP, "heap_update_undo: unimplemented");
|
||||
@ -2606,19 +2614,19 @@ newsame:;
|
||||
static void
|
||||
_heap_unlock_tuple(void *data)
|
||||
{
|
||||
xl_heaptid *xltid = (xl_heaptid*) data;
|
||||
Relation reln = XLogOpenRelation(false, RM_HEAP_ID, xltid->node);
|
||||
Buffer buffer;
|
||||
Page page;
|
||||
OffsetNumber offnum;
|
||||
ItemId lp;
|
||||
HeapTupleHeader htup;
|
||||
xl_heaptid *xltid = (xl_heaptid *) data;
|
||||
Relation reln = XLogOpenRelation(false, RM_HEAP_ID, xltid->node);
|
||||
Buffer buffer;
|
||||
Page page;
|
||||
OffsetNumber offnum;
|
||||
ItemId lp;
|
||||
HeapTupleHeader htup;
|
||||
|
||||
if (!RelationIsValid(reln))
|
||||
elog(STOP, "_heap_unlock_tuple: can't open relation");
|
||||
|
||||
buffer = XLogReadBuffer(false, reln,
|
||||
ItemPointerGetBlockNumber(&(xltid->tid)));
|
||||
buffer = XLogReadBuffer(false, reln,
|
||||
ItemPointerGetBlockNumber(&(xltid->tid)));
|
||||
if (!BufferIsValid(buffer))
|
||||
elog(STOP, "_heap_unlock_tuple: can't read buffer");
|
||||
|
||||
@ -2636,8 +2644,8 @@ _heap_unlock_tuple(void *data)
|
||||
|
||||
htup = (HeapTupleHeader) PageGetItem(page, lp);
|
||||
|
||||
if (htup->t_xmax != GetCurrentTransactionId() ||
|
||||
htup->t_cmax != GetCurrentCommandId())
|
||||
if (htup->t_xmax != GetCurrentTransactionId() ||
|
||||
htup->t_cmax != GetCurrentCommandId())
|
||||
elog(STOP, "_heap_unlock_tuple: invalid xmax/cmax in rollback");
|
||||
htup->t_infomask &= ~HEAP_XMAX_UNLOGGED;
|
||||
htup->t_infomask |= HEAP_XMAX_INVALID;
|
||||
@ -2645,9 +2653,10 @@ _heap_unlock_tuple(void *data)
|
||||
return;
|
||||
}
|
||||
|
||||
void heap_redo(XLogRecPtr lsn, XLogRecord *record)
|
||||
void
|
||||
heap_redo(XLogRecPtr lsn, XLogRecord *record)
|
||||
{
|
||||
uint8 info = record->xl_info & ~XLR_INFO_MASK;
|
||||
uint8 info = record->xl_info & ~XLR_INFO_MASK;
|
||||
|
||||
info &= XLOG_HEAP_OPMASK;
|
||||
if (info == XLOG_HEAP_INSERT)
|
||||
@ -2664,9 +2673,10 @@ void heap_redo(XLogRecPtr lsn, XLogRecord *record)
|
||||
elog(STOP, "heap_redo: unknown op code %u", info);
|
||||
}
|
||||
|
||||
void heap_undo(XLogRecPtr lsn, XLogRecord *record)
|
||||
void
|
||||
heap_undo(XLogRecPtr lsn, XLogRecord *record)
|
||||
{
|
||||
uint8 info = record->xl_info & ~XLR_INFO_MASK;
|
||||
uint8 info = record->xl_info & ~XLR_INFO_MASK;
|
||||
|
||||
info &= XLOG_HEAP_OPMASK;
|
||||
if (info == XLOG_HEAP_INSERT)
|
||||
@ -2687,46 +2697,50 @@ static void
|
||||
out_target(char *buf, xl_heaptid *target)
|
||||
{
|
||||
sprintf(buf + strlen(buf), "node %u/%u; tid %u/%u",
|
||||
target->node.tblNode, target->node.relNode,
|
||||
ItemPointerGetBlockNumber(&(target->tid)),
|
||||
ItemPointerGetOffsetNumber(&(target->tid)));
|
||||
target->node.tblNode, target->node.relNode,
|
||||
ItemPointerGetBlockNumber(&(target->tid)),
|
||||
ItemPointerGetOffsetNumber(&(target->tid)));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
heap_desc(char *buf, uint8 xl_info, char* rec)
|
||||
heap_desc(char *buf, uint8 xl_info, char *rec)
|
||||
{
|
||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||
uint8 info = xl_info & ~XLR_INFO_MASK;
|
||||
|
||||
info &= XLOG_HEAP_OPMASK;
|
||||
if (info == XLOG_HEAP_INSERT)
|
||||
{
|
||||
xl_heap_insert *xlrec = (xl_heap_insert*) rec;
|
||||
xl_heap_insert *xlrec = (xl_heap_insert *) rec;
|
||||
|
||||
strcat(buf, "insert: ");
|
||||
out_target(buf, &(xlrec->target));
|
||||
}
|
||||
else if (info == XLOG_HEAP_DELETE)
|
||||
{
|
||||
xl_heap_delete *xlrec = (xl_heap_delete*) rec;
|
||||
xl_heap_delete *xlrec = (xl_heap_delete *) rec;
|
||||
|
||||
strcat(buf, "delete: ");
|
||||
out_target(buf, &(xlrec->target));
|
||||
}
|
||||
else if (info == XLOG_HEAP_UPDATE || info == XLOG_HEAP_MOVE)
|
||||
{
|
||||
xl_heap_update *xlrec = (xl_heap_update*) rec;
|
||||
xl_heap_update *xlrec = (xl_heap_update *) rec;
|
||||
|
||||
if (info == XLOG_HEAP_UPDATE)
|
||||
strcat(buf, "update: ");
|
||||
else
|
||||
strcat(buf, "move: ");
|
||||
out_target(buf, &(xlrec->target));
|
||||
sprintf(buf + strlen(buf), "; new %u/%u",
|
||||
ItemPointerGetBlockNumber(&(xlrec->newtid)),
|
||||
ItemPointerGetOffsetNumber(&(xlrec->newtid)));
|
||||
ItemPointerGetBlockNumber(&(xlrec->newtid)),
|
||||
ItemPointerGetOffsetNumber(&(xlrec->newtid)));
|
||||
}
|
||||
else if (info == XLOG_HEAP_CLEAN)
|
||||
{
|
||||
xl_heap_clean *xlrec = (xl_heap_clean*) rec;
|
||||
xl_heap_clean *xlrec = (xl_heap_clean *) rec;
|
||||
|
||||
sprintf(buf + strlen(buf), "clean: node %u/%u; blk %u",
|
||||
xlrec->node.tblNode, xlrec->node.relNode, xlrec->block);
|
||||
xlrec->node.tblNode, xlrec->node.relNode, xlrec->block);
|
||||
}
|
||||
else
|
||||
strcat(buf, "UNKNOWN");
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Id: hio.c,v 1.35 2001/01/24 19:42:48 momjian Exp $
|
||||
* $Id: hio.c,v 1.36 2001/03/22 03:59:13 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -19,7 +19,7 @@
|
||||
#include "access/hio.h"
|
||||
|
||||
/*
|
||||
* RelationPutHeapTuple - place tuple at specified page
|
||||
* RelationPutHeapTuple - place tuple at specified page
|
||||
*
|
||||
* !!! ELOG(ERROR) IS DISALLOWED HERE !!!
|
||||
*
|
||||
@ -69,7 +69,7 @@ RelationPutHeapTuple(Relation relation,
|
||||
*
|
||||
* Returns (locked) buffer with free space >= given len.
|
||||
*
|
||||
* Note that we use LockPage to lock relation for extension. We can
|
||||
* Note that we use LockPage to lock relation for extension. We can
|
||||
* do this as long as in all other places we use page-level locking
|
||||
* for indices only. Alternatively, we could define pseudo-table as
|
||||
* we do for transactions with XactLockTable.
|
||||
@ -92,7 +92,7 @@ RelationGetBufferForTuple(Relation relation, Size len)
|
||||
*/
|
||||
if (len > MaxTupleSize)
|
||||
elog(ERROR, "Tuple is too big: size %lu, max size %ld",
|
||||
(unsigned long)len, MaxTupleSize);
|
||||
(unsigned long) len, MaxTupleSize);
|
||||
|
||||
if (!relation->rd_myxactonly)
|
||||
LockPage(relation, 0, ExclusiveLock);
|
||||
@ -140,13 +140,13 @@ RelationGetBufferForTuple(Relation relation, Size len)
|
||||
{
|
||||
/* We should not get here given the test at the top */
|
||||
elog(STOP, "Tuple is too big: size %lu",
|
||||
(unsigned long)len);
|
||||
(unsigned long) len);
|
||||
}
|
||||
}
|
||||
|
||||
if (!relation->rd_myxactonly)
|
||||
UnlockPage(relation, 0, ExclusiveLock);
|
||||
|
||||
return(buffer);
|
||||
return (buffer);
|
||||
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.17 2001/02/15 20:57:01 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.18 2001/03/22 03:59:13 momjian Exp $
|
||||
*
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
@ -41,12 +41,12 @@
|
||||
|
||||
#undef TOAST_DEBUG
|
||||
|
||||
static void toast_delete(Relation rel, HeapTuple oldtup);
|
||||
static void toast_delete_datum(Relation rel, Datum value);
|
||||
static void toast_insert_or_update(Relation rel, HeapTuple newtup,
|
||||
HeapTuple oldtup);
|
||||
static Datum toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value);
|
||||
static varattrib *toast_fetch_datum(varattrib *attr);
|
||||
static void toast_delete(Relation rel, HeapTuple oldtup);
|
||||
static void toast_delete_datum(Relation rel, Datum value);
|
||||
static void toast_insert_or_update(Relation rel, HeapTuple newtup,
|
||||
HeapTuple oldtup);
|
||||
static Datum toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value);
|
||||
static varattrib *toast_fetch_datum(varattrib *attr);
|
||||
|
||||
|
||||
/* ----------
|
||||
@ -70,14 +70,14 @@ heap_tuple_toast_attrs(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
/* ----------
|
||||
* heap_tuple_fetch_attr -
|
||||
*
|
||||
* Public entry point to get back a toasted value
|
||||
* Public entry point to get back a toasted value
|
||||
* external storage (possibly still in compressed format).
|
||||
* ----------
|
||||
*/
|
||||
varattrib *
|
||||
varattrib *
|
||||
heap_tuple_fetch_attr(varattrib *attr)
|
||||
{
|
||||
varattrib *result;
|
||||
varattrib *result;
|
||||
|
||||
if (VARATT_IS_EXTERNAL(attr))
|
||||
{
|
||||
@ -94,7 +94,7 @@ heap_tuple_fetch_attr(varattrib *attr)
|
||||
* ----------
|
||||
*/
|
||||
result = attr;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -107,10 +107,10 @@ heap_tuple_fetch_attr(varattrib *attr)
|
||||
* or external storage.
|
||||
* ----------
|
||||
*/
|
||||
varattrib *
|
||||
varattrib *
|
||||
heap_tuple_untoast_attr(varattrib *attr)
|
||||
{
|
||||
varattrib *result;
|
||||
varattrib *result;
|
||||
|
||||
if (VARATT_IS_EXTERNAL(attr))
|
||||
{
|
||||
@ -121,14 +121,14 @@ heap_tuple_untoast_attr(varattrib *attr)
|
||||
* Fetch it from the toast heap and decompress.
|
||||
* ----------
|
||||
*/
|
||||
varattrib *tmp;
|
||||
varattrib *tmp;
|
||||
|
||||
tmp = toast_fetch_datum(attr);
|
||||
result = (varattrib *)palloc(attr->va_content.va_external.va_rawsize
|
||||
+ VARHDRSZ);
|
||||
result = (varattrib *) palloc(attr->va_content.va_external.va_rawsize
|
||||
+ VARHDRSZ);
|
||||
VARATT_SIZEP(result) = attr->va_content.va_external.va_rawsize
|
||||
+ VARHDRSZ;
|
||||
pglz_decompress((PGLZ_Header *)tmp, VARATT_DATA(result));
|
||||
+ VARHDRSZ;
|
||||
pglz_decompress((PGLZ_Header *) tmp, VARATT_DATA(result));
|
||||
|
||||
pfree(tmp);
|
||||
}
|
||||
@ -147,11 +147,11 @@ heap_tuple_untoast_attr(varattrib *attr)
|
||||
* This is a compressed value inside of the main tuple
|
||||
* ----------
|
||||
*/
|
||||
result = (varattrib *)palloc(attr->va_content.va_compressed.va_rawsize
|
||||
+ VARHDRSZ);
|
||||
result = (varattrib *) palloc(attr->va_content.va_compressed.va_rawsize
|
||||
+ VARHDRSZ);
|
||||
VARATT_SIZEP(result) = attr->va_content.va_compressed.va_rawsize
|
||||
+ VARHDRSZ;
|
||||
pglz_decompress((PGLZ_Header *)attr, VARATT_DATA(result));
|
||||
+ VARHDRSZ;
|
||||
pglz_decompress((PGLZ_Header *) attr, VARATT_DATA(result));
|
||||
}
|
||||
else
|
||||
/* ----------
|
||||
@ -173,21 +173,21 @@ heap_tuple_untoast_attr(varattrib *attr)
|
||||
static void
|
||||
toast_delete(Relation rel, HeapTuple oldtup)
|
||||
{
|
||||
TupleDesc tupleDesc;
|
||||
Form_pg_attribute *att;
|
||||
int numAttrs;
|
||||
int i;
|
||||
Datum value;
|
||||
bool isnull;
|
||||
TupleDesc tupleDesc;
|
||||
Form_pg_attribute *att;
|
||||
int numAttrs;
|
||||
int i;
|
||||
Datum value;
|
||||
bool isnull;
|
||||
|
||||
/* ----------
|
||||
* Get the tuple descriptor, the number of and attribute
|
||||
* descriptors.
|
||||
* ----------
|
||||
*/
|
||||
tupleDesc = rel->rd_att;
|
||||
numAttrs = tupleDesc->natts;
|
||||
att = tupleDesc->attrs;
|
||||
tupleDesc = rel->rd_att;
|
||||
numAttrs = tupleDesc->natts;
|
||||
att = tupleDesc->attrs;
|
||||
|
||||
/* ----------
|
||||
* Check for external stored attributes and delete them
|
||||
@ -216,35 +216,35 @@ toast_delete(Relation rel, HeapTuple oldtup)
|
||||
static void
|
||||
toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
{
|
||||
TupleDesc tupleDesc;
|
||||
Form_pg_attribute *att;
|
||||
int numAttrs;
|
||||
int i;
|
||||
bool old_isnull;
|
||||
bool new_isnull;
|
||||
TupleDesc tupleDesc;
|
||||
Form_pg_attribute *att;
|
||||
int numAttrs;
|
||||
int i;
|
||||
bool old_isnull;
|
||||
bool new_isnull;
|
||||
|
||||
bool need_change = false;
|
||||
bool need_free = false;
|
||||
bool need_delold = false;
|
||||
bool has_nulls = false;
|
||||
bool need_change = false;
|
||||
bool need_free = false;
|
||||
bool need_delold = false;
|
||||
bool has_nulls = false;
|
||||
|
||||
Size maxDataLen;
|
||||
Size maxDataLen;
|
||||
|
||||
char toast_action[MaxHeapAttributeNumber];
|
||||
char toast_nulls[MaxHeapAttributeNumber];
|
||||
Datum toast_values[MaxHeapAttributeNumber];
|
||||
int32 toast_sizes[MaxHeapAttributeNumber];
|
||||
bool toast_free[MaxHeapAttributeNumber];
|
||||
bool toast_delold[MaxHeapAttributeNumber];
|
||||
char toast_action[MaxHeapAttributeNumber];
|
||||
char toast_nulls[MaxHeapAttributeNumber];
|
||||
Datum toast_values[MaxHeapAttributeNumber];
|
||||
int32 toast_sizes[MaxHeapAttributeNumber];
|
||||
bool toast_free[MaxHeapAttributeNumber];
|
||||
bool toast_delold[MaxHeapAttributeNumber];
|
||||
|
||||
/* ----------
|
||||
* Get the tuple descriptor, the number of and attribute
|
||||
* descriptors and the location of the tuple values.
|
||||
* ----------
|
||||
*/
|
||||
tupleDesc = rel->rd_att;
|
||||
numAttrs = tupleDesc->natts;
|
||||
att = tupleDesc->attrs;
|
||||
tupleDesc = rel->rd_att;
|
||||
numAttrs = tupleDesc->natts;
|
||||
att = tupleDesc->attrs;
|
||||
|
||||
/* ----------
|
||||
* Then collect information about the values given
|
||||
@ -255,14 +255,14 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
* 'x' incompressible, but OK to move off
|
||||
* ----------
|
||||
*/
|
||||
memset(toast_action, ' ', numAttrs * sizeof(char));
|
||||
memset(toast_nulls, ' ', numAttrs * sizeof(char));
|
||||
memset(toast_free, 0, numAttrs * sizeof(bool));
|
||||
memset(toast_delold, 0, numAttrs * sizeof(bool));
|
||||
memset(toast_action, ' ', numAttrs * sizeof(char));
|
||||
memset(toast_nulls, ' ', numAttrs * sizeof(char));
|
||||
memset(toast_free, 0, numAttrs * sizeof(bool));
|
||||
memset(toast_delold, 0, numAttrs * sizeof(bool));
|
||||
for (i = 0; i < numAttrs; i++)
|
||||
{
|
||||
varattrib *old_value;
|
||||
varattrib *new_value;
|
||||
varattrib *old_value;
|
||||
varattrib *new_value;
|
||||
|
||||
if (oldtup != NULL)
|
||||
{
|
||||
@ -270,25 +270,25 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
* For UPDATE get the old and new values of this attribute
|
||||
* ----------
|
||||
*/
|
||||
old_value = (varattrib *)DatumGetPointer(
|
||||
heap_getattr(oldtup, i + 1, tupleDesc, &old_isnull));
|
||||
toast_values[i] =
|
||||
heap_getattr(newtup, i + 1, tupleDesc, &new_isnull);
|
||||
new_value = (varattrib *)DatumGetPointer(toast_values[i]);
|
||||
old_value = (varattrib *) DatumGetPointer(
|
||||
heap_getattr(oldtup, i + 1, tupleDesc, &old_isnull));
|
||||
toast_values[i] =
|
||||
heap_getattr(newtup, i + 1, tupleDesc, &new_isnull);
|
||||
new_value = (varattrib *) DatumGetPointer(toast_values[i]);
|
||||
|
||||
/* ----------
|
||||
* If the old value is an external stored one, check if it
|
||||
* has changed so we have to delete it later.
|
||||
* ----------
|
||||
*/
|
||||
if (!old_isnull && att[i]->attlen == -1 &&
|
||||
VARATT_IS_EXTERNAL(old_value))
|
||||
if (!old_isnull && att[i]->attlen == -1 &&
|
||||
VARATT_IS_EXTERNAL(old_value))
|
||||
{
|
||||
if (new_isnull || !VARATT_IS_EXTERNAL(new_value) ||
|
||||
old_value->va_content.va_external.va_rowid !=
|
||||
new_value->va_content.va_external.va_rowid ||
|
||||
old_value->va_content.va_external.va_attno !=
|
||||
new_value->va_content.va_external.va_attno)
|
||||
old_value->va_content.va_external.va_rowid !=
|
||||
new_value->va_content.va_external.va_rowid ||
|
||||
old_value->va_content.va_external.va_attno !=
|
||||
new_value->va_content.va_external.va_attno)
|
||||
{
|
||||
/* ----------
|
||||
* The old external store value isn't needed any
|
||||
@ -318,8 +318,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
* For INSERT simply get the new value
|
||||
* ----------
|
||||
*/
|
||||
toast_values[i] =
|
||||
heap_getattr(newtup, i + 1, tupleDesc, &new_isnull);
|
||||
toast_values[i] =
|
||||
heap_getattr(newtup, i + 1, tupleDesc, &new_isnull);
|
||||
}
|
||||
|
||||
/* ----------
|
||||
@ -356,7 +356,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
if (VARATT_IS_EXTERNAL(DatumGetPointer(toast_values[i])))
|
||||
{
|
||||
toast_values[i] = PointerGetDatum(heap_tuple_untoast_attr(
|
||||
(varattrib *)DatumGetPointer(toast_values[i])));
|
||||
(varattrib *) DatumGetPointer(toast_values[i])));
|
||||
toast_free[i] = true;
|
||||
need_change = true;
|
||||
need_free = true;
|
||||
@ -366,7 +366,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
* Remember the size of this attribute
|
||||
* ----------
|
||||
*/
|
||||
toast_sizes[i] = VARATT_SIZE(DatumGetPointer(toast_values[i]));
|
||||
toast_sizes[i] = VARATT_SIZE(DatumGetPointer(toast_values[i]));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -375,7 +375,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
* ----------
|
||||
*/
|
||||
toast_action[i] = 'p';
|
||||
toast_sizes[i] = att[i]->attlen;
|
||||
toast_sizes[i] = att[i]->attlen;
|
||||
}
|
||||
}
|
||||
|
||||
@ -384,7 +384,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
*
|
||||
* 1: Inline compress attributes with attstorage 'x'
|
||||
* 2: Store attributes with attstorage 'x' or 'e' external
|
||||
* 3: Inline compress attributes with attstorage 'm'
|
||||
* 3: Inline compress attributes with attstorage 'm'
|
||||
* 4: Store attributes with attstorage 'm' external
|
||||
* ----------
|
||||
*/
|
||||
@ -398,12 +398,12 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
* ----------
|
||||
*/
|
||||
while (MAXALIGN(ComputeDataSize(tupleDesc, toast_values, toast_nulls)) >
|
||||
maxDataLen)
|
||||
maxDataLen)
|
||||
{
|
||||
int biggest_attno = -1;
|
||||
int32 biggest_size = MAXALIGN(sizeof(varattrib));
|
||||
Datum old_value;
|
||||
Datum new_value;
|
||||
int biggest_attno = -1;
|
||||
int32 biggest_size = MAXALIGN(sizeof(varattrib));
|
||||
Datum old_value;
|
||||
Datum new_value;
|
||||
|
||||
/* ----------
|
||||
* Search for the biggest yet uncompressed internal attribute
|
||||
@ -420,7 +420,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
if (toast_sizes[i] > biggest_size)
|
||||
{
|
||||
biggest_attno = i;
|
||||
biggest_size = toast_sizes[i];
|
||||
biggest_size = toast_sizes[i];
|
||||
}
|
||||
}
|
||||
|
||||
@ -431,24 +431,28 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
* Attempt to compress it inline
|
||||
* ----------
|
||||
*/
|
||||
i = biggest_attno;
|
||||
old_value = toast_values[i];
|
||||
new_value = toast_compress_datum(old_value);
|
||||
i = biggest_attno;
|
||||
old_value = toast_values[i];
|
||||
new_value = toast_compress_datum(old_value);
|
||||
|
||||
if (DatumGetPointer(new_value) != NULL)
|
||||
{
|
||||
/* successful compression */
|
||||
if (toast_free[i])
|
||||
pfree(DatumGetPointer(old_value));
|
||||
toast_values[i] = new_value;
|
||||
toast_free[i] = true;
|
||||
toast_sizes[i] = VARATT_SIZE(toast_values[i]);
|
||||
need_change = true;
|
||||
need_free = true;
|
||||
toast_values[i] = new_value;
|
||||
toast_free[i] = true;
|
||||
toast_sizes[i] = VARATT_SIZE(toast_values[i]);
|
||||
need_change = true;
|
||||
need_free = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incompressible data, ignore on subsequent compression passes */
|
||||
|
||||
/*
|
||||
* incompressible data, ignore on subsequent compression
|
||||
* passes
|
||||
*/
|
||||
toast_action[i] = 'x';
|
||||
}
|
||||
}
|
||||
@ -459,11 +463,11 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
* ----------
|
||||
*/
|
||||
while (MAXALIGN(ComputeDataSize(tupleDesc, toast_values, toast_nulls)) >
|
||||
maxDataLen && rel->rd_rel->reltoastrelid != InvalidOid)
|
||||
maxDataLen && rel->rd_rel->reltoastrelid != InvalidOid)
|
||||
{
|
||||
int biggest_attno = -1;
|
||||
int32 biggest_size = MAXALIGN(sizeof(varattrib));
|
||||
Datum old_value;
|
||||
int biggest_attno = -1;
|
||||
int32 biggest_size = MAXALIGN(sizeof(varattrib));
|
||||
Datum old_value;
|
||||
|
||||
/* ----------
|
||||
* Search for the biggest yet inlined attribute with
|
||||
@ -481,7 +485,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
if (toast_sizes[i] > biggest_size)
|
||||
{
|
||||
biggest_attno = i;
|
||||
biggest_size = toast_sizes[i];
|
||||
biggest_size = toast_sizes[i];
|
||||
}
|
||||
}
|
||||
|
||||
@ -492,21 +496,21 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
* Store this external
|
||||
* ----------
|
||||
*/
|
||||
i = biggest_attno;
|
||||
old_value = toast_values[i];
|
||||
toast_action[i] = 'p';
|
||||
toast_values[i] = toast_save_datum(rel,
|
||||
newtup->t_data->t_oid,
|
||||
i + 1,
|
||||
toast_values[i]);
|
||||
i = biggest_attno;
|
||||
old_value = toast_values[i];
|
||||
toast_action[i] = 'p';
|
||||
toast_values[i] = toast_save_datum(rel,
|
||||
newtup->t_data->t_oid,
|
||||
i + 1,
|
||||
toast_values[i]);
|
||||
if (toast_free[i])
|
||||
pfree(DatumGetPointer(old_value));
|
||||
|
||||
toast_free[i] = true;
|
||||
toast_sizes[i] = VARATT_SIZE(toast_values[i]);
|
||||
toast_free[i] = true;
|
||||
toast_sizes[i] = VARATT_SIZE(toast_values[i]);
|
||||
|
||||
need_change = true;
|
||||
need_free = true;
|
||||
need_free = true;
|
||||
}
|
||||
|
||||
/* ----------
|
||||
@ -515,12 +519,12 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
* ----------
|
||||
*/
|
||||
while (MAXALIGN(ComputeDataSize(tupleDesc, toast_values, toast_nulls)) >
|
||||
maxDataLen)
|
||||
maxDataLen)
|
||||
{
|
||||
int biggest_attno = -1;
|
||||
int32 biggest_size = MAXALIGN(sizeof(varattrib));
|
||||
Datum old_value;
|
||||
Datum new_value;
|
||||
int biggest_attno = -1;
|
||||
int32 biggest_size = MAXALIGN(sizeof(varattrib));
|
||||
Datum old_value;
|
||||
Datum new_value;
|
||||
|
||||
/* ----------
|
||||
* Search for the biggest yet uncompressed internal attribute
|
||||
@ -537,7 +541,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
if (toast_sizes[i] > biggest_size)
|
||||
{
|
||||
biggest_attno = i;
|
||||
biggest_size = toast_sizes[i];
|
||||
biggest_size = toast_sizes[i];
|
||||
}
|
||||
}
|
||||
|
||||
@ -548,24 +552,28 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
* Attempt to compress it inline
|
||||
* ----------
|
||||
*/
|
||||
i = biggest_attno;
|
||||
old_value = toast_values[i];
|
||||
new_value = toast_compress_datum(old_value);
|
||||
i = biggest_attno;
|
||||
old_value = toast_values[i];
|
||||
new_value = toast_compress_datum(old_value);
|
||||
|
||||
if (DatumGetPointer(new_value) != NULL)
|
||||
{
|
||||
/* successful compression */
|
||||
if (toast_free[i])
|
||||
pfree(DatumGetPointer(old_value));
|
||||
toast_values[i] = new_value;
|
||||
toast_free[i] = true;
|
||||
toast_sizes[i] = VARATT_SIZE(toast_values[i]);
|
||||
need_change = true;
|
||||
need_free = true;
|
||||
toast_values[i] = new_value;
|
||||
toast_free[i] = true;
|
||||
toast_sizes[i] = VARATT_SIZE(toast_values[i]);
|
||||
need_change = true;
|
||||
need_free = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* incompressible data, ignore on subsequent compression passes */
|
||||
|
||||
/*
|
||||
* incompressible data, ignore on subsequent compression
|
||||
* passes
|
||||
*/
|
||||
toast_action[i] = 'x';
|
||||
}
|
||||
}
|
||||
@ -575,11 +583,11 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
* ----------
|
||||
*/
|
||||
while (MAXALIGN(ComputeDataSize(tupleDesc, toast_values, toast_nulls)) >
|
||||
maxDataLen && rel->rd_rel->reltoastrelid != InvalidOid)
|
||||
maxDataLen && rel->rd_rel->reltoastrelid != InvalidOid)
|
||||
{
|
||||
int biggest_attno = -1;
|
||||
int32 biggest_size = MAXALIGN(sizeof(varattrib));
|
||||
Datum old_value;
|
||||
int biggest_attno = -1;
|
||||
int32 biggest_size = MAXALIGN(sizeof(varattrib));
|
||||
Datum old_value;
|
||||
|
||||
/* ----------
|
||||
* Search for the biggest yet inlined attribute with
|
||||
@ -597,7 +605,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
if (toast_sizes[i] > biggest_size)
|
||||
{
|
||||
biggest_attno = i;
|
||||
biggest_size = toast_sizes[i];
|
||||
biggest_size = toast_sizes[i];
|
||||
}
|
||||
}
|
||||
|
||||
@ -608,21 +616,21 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
* Store this external
|
||||
* ----------
|
||||
*/
|
||||
i = biggest_attno;
|
||||
old_value = toast_values[i];
|
||||
toast_action[i] = 'p';
|
||||
toast_values[i] = toast_save_datum(rel,
|
||||
newtup->t_data->t_oid,
|
||||
i + 1,
|
||||
toast_values[i]);
|
||||
i = biggest_attno;
|
||||
old_value = toast_values[i];
|
||||
toast_action[i] = 'p';
|
||||
toast_values[i] = toast_save_datum(rel,
|
||||
newtup->t_data->t_oid,
|
||||
i + 1,
|
||||
toast_values[i]);
|
||||
if (toast_free[i])
|
||||
pfree(DatumGetPointer(old_value));
|
||||
|
||||
toast_free[i] = true;
|
||||
toast_sizes[i] = VARATT_SIZE(toast_values[i]);
|
||||
toast_free[i] = true;
|
||||
toast_sizes[i] = VARATT_SIZE(toast_values[i]);
|
||||
|
||||
need_change = true;
|
||||
need_free = true;
|
||||
need_free = true;
|
||||
}
|
||||
|
||||
/* ----------
|
||||
@ -632,10 +640,10 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
*/
|
||||
if (need_change)
|
||||
{
|
||||
char *new_data;
|
||||
int32 new_len;
|
||||
MemoryContext oldcxt;
|
||||
HeapTupleHeader olddata;
|
||||
char *new_data;
|
||||
int32 new_len;
|
||||
MemoryContext oldcxt;
|
||||
HeapTupleHeader olddata;
|
||||
|
||||
/* ----------
|
||||
* Calculate the new size of the tuple
|
||||
@ -662,24 +670,24 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
* ----------
|
||||
*/
|
||||
memcpy(new_data, newtup->t_data, newtup->t_data->t_hoff);
|
||||
newtup->t_data = (HeapTupleHeader)new_data;
|
||||
newtup->t_data = (HeapTupleHeader) new_data;
|
||||
newtup->t_len = new_len;
|
||||
|
||||
DataFill((char *)(MAXALIGN((long)new_data +
|
||||
offsetof(HeapTupleHeaderData, t_bits) +
|
||||
((has_nulls) ? BITMAPLEN(numAttrs) : 0))),
|
||||
tupleDesc,
|
||||
toast_values,
|
||||
toast_nulls,
|
||||
&(newtup->t_data->t_infomask),
|
||||
has_nulls ? newtup->t_data->t_bits : NULL);
|
||||
DataFill((char *) (MAXALIGN((long) new_data +
|
||||
offsetof(HeapTupleHeaderData, t_bits) +
|
||||
((has_nulls) ? BITMAPLEN(numAttrs) : 0))),
|
||||
tupleDesc,
|
||||
toast_values,
|
||||
toast_nulls,
|
||||
&(newtup->t_data->t_infomask),
|
||||
has_nulls ? newtup->t_data->t_bits : NULL);
|
||||
|
||||
/* ----------
|
||||
* In the case we modified a previously modified tuple again,
|
||||
* free the memory from the previous run
|
||||
* ----------
|
||||
*/
|
||||
if ((char *)olddata != ((char *)newtup + HEAPTUPLESIZE))
|
||||
if ((char *) olddata != ((char *) newtup + HEAPTUPLESIZE))
|
||||
pfree(olddata);
|
||||
|
||||
/* ----------
|
||||
@ -723,7 +731,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
Datum
|
||||
toast_compress_datum(Datum value)
|
||||
{
|
||||
varattrib *tmp;
|
||||
varattrib *tmp;
|
||||
|
||||
tmp = (varattrib *) palloc(sizeof(PGLZ_Header) + VARATT_SIZE(value));
|
||||
pglz_compress(VARATT_DATA(value), VARATT_SIZE(value) - VARHDRSZ,
|
||||
@ -754,45 +762,45 @@ toast_compress_datum(Datum value)
|
||||
static Datum
|
||||
toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
|
||||
{
|
||||
Relation toastrel;
|
||||
Relation toastidx;
|
||||
HeapTuple toasttup;
|
||||
InsertIndexResult idxres;
|
||||
TupleDesc toasttupDesc;
|
||||
Datum t_values[3];
|
||||
char t_nulls[3];
|
||||
varattrib *result;
|
||||
char chunk_data[VARHDRSZ + TOAST_MAX_CHUNK_SIZE];
|
||||
int32 chunk_size;
|
||||
int32 chunk_seq = 0;
|
||||
char *data_p;
|
||||
int32 data_todo;
|
||||
Relation toastrel;
|
||||
Relation toastidx;
|
||||
HeapTuple toasttup;
|
||||
InsertIndexResult idxres;
|
||||
TupleDesc toasttupDesc;
|
||||
Datum t_values[3];
|
||||
char t_nulls[3];
|
||||
varattrib *result;
|
||||
char chunk_data[VARHDRSZ + TOAST_MAX_CHUNK_SIZE];
|
||||
int32 chunk_size;
|
||||
int32 chunk_seq = 0;
|
||||
char *data_p;
|
||||
int32 data_todo;
|
||||
|
||||
/* ----------
|
||||
* Create the varattrib reference
|
||||
* ----------
|
||||
*/
|
||||
result = (varattrib *)palloc(sizeof(varattrib));
|
||||
result = (varattrib *) palloc(sizeof(varattrib));
|
||||
|
||||
result->va_header = sizeof(varattrib) | VARATT_FLAG_EXTERNAL;
|
||||
result->va_header = sizeof(varattrib) | VARATT_FLAG_EXTERNAL;
|
||||
if (VARATT_IS_COMPRESSED(value))
|
||||
{
|
||||
result->va_header |= VARATT_FLAG_COMPRESSED;
|
||||
result->va_content.va_external.va_rawsize =
|
||||
((varattrib *)value)->va_content.va_compressed.va_rawsize;
|
||||
result->va_content.va_external.va_rawsize =
|
||||
((varattrib *) value)->va_content.va_compressed.va_rawsize;
|
||||
}
|
||||
else
|
||||
result->va_content.va_external.va_rawsize = VARATT_SIZE(value);
|
||||
|
||||
result->va_content.va_external.va_extsize =
|
||||
VARATT_SIZE(value) - VARHDRSZ;
|
||||
result->va_content.va_external.va_valueid = newoid();
|
||||
result->va_content.va_external.va_toastrelid =
|
||||
rel->rd_rel->reltoastrelid;
|
||||
result->va_content.va_external.va_toastidxid =
|
||||
rel->rd_rel->reltoastidxid;
|
||||
result->va_content.va_external.va_rowid = mainoid;
|
||||
result->va_content.va_external.va_attno = attno;
|
||||
|
||||
result->va_content.va_external.va_extsize =
|
||||
VARATT_SIZE(value) - VARHDRSZ;
|
||||
result->va_content.va_external.va_valueid = newoid();
|
||||
result->va_content.va_external.va_toastrelid =
|
||||
rel->rd_rel->reltoastrelid;
|
||||
result->va_content.va_external.va_toastidxid =
|
||||
rel->rd_rel->reltoastidxid;
|
||||
result->va_content.va_external.va_rowid = mainoid;
|
||||
result->va_content.va_external.va_attno = attno;
|
||||
|
||||
/* ----------
|
||||
* Initialize constant parts of the tuple data
|
||||
@ -808,8 +816,8 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
|
||||
* Get the data to process
|
||||
* ----------
|
||||
*/
|
||||
data_p = VARATT_DATA(value);
|
||||
data_todo = VARATT_SIZE(value) - VARHDRSZ;
|
||||
data_p = VARATT_DATA(value);
|
||||
data_todo = VARATT_SIZE(value) - VARHDRSZ;
|
||||
|
||||
/* ----------
|
||||
* Open the toast relation
|
||||
@ -818,9 +826,9 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
|
||||
toastrel = heap_open(rel->rd_rel->reltoastrelid, RowExclusiveLock);
|
||||
toasttupDesc = toastrel->rd_att;
|
||||
toastidx = index_open(rel->rd_rel->reltoastidxid);
|
||||
|
||||
|
||||
/* ----------
|
||||
* Split up the item into chunks
|
||||
* Split up the item into chunks
|
||||
* ----------
|
||||
*/
|
||||
while (data_todo > 0)
|
||||
@ -848,8 +856,8 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
|
||||
*/
|
||||
heap_insert(toastrel, toasttup);
|
||||
idxres = index_insert(toastidx, t_values, t_nulls,
|
||||
&(toasttup->t_self),
|
||||
toastrel);
|
||||
&(toasttup->t_self),
|
||||
toastrel);
|
||||
if (idxres == NULL)
|
||||
elog(ERROR, "Failed to insert index entry for TOAST tuple");
|
||||
|
||||
@ -888,14 +896,14 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
|
||||
static void
|
||||
toast_delete_datum(Relation rel, Datum value)
|
||||
{
|
||||
register varattrib *attr = (varattrib *)value;
|
||||
Relation toastrel;
|
||||
Relation toastidx;
|
||||
ScanKeyData toastkey;
|
||||
IndexScanDesc toastscan;
|
||||
HeapTupleData toasttup;
|
||||
RetrieveIndexResult indexRes;
|
||||
Buffer buffer;
|
||||
register varattrib *attr = (varattrib *) value;
|
||||
Relation toastrel;
|
||||
Relation toastidx;
|
||||
ScanKeyData toastkey;
|
||||
IndexScanDesc toastscan;
|
||||
HeapTupleData toasttup;
|
||||
RetrieveIndexResult indexRes;
|
||||
Buffer buffer;
|
||||
|
||||
if (!VARATT_IS_EXTERNAL(attr))
|
||||
return;
|
||||
@ -904,8 +912,8 @@ toast_delete_datum(Relation rel, Datum value)
|
||||
* Open the toast relation and it's index
|
||||
* ----------
|
||||
*/
|
||||
toastrel = heap_open(attr->va_content.va_external.va_toastrelid,
|
||||
RowExclusiveLock);
|
||||
toastrel = heap_open(attr->va_content.va_external.va_toastrelid,
|
||||
RowExclusiveLock);
|
||||
toastidx = index_open(attr->va_content.va_external.va_toastidxid);
|
||||
|
||||
/* ----------
|
||||
@ -913,10 +921,10 @@ toast_delete_datum(Relation rel, Datum value)
|
||||
* ----------
|
||||
*/
|
||||
ScanKeyEntryInitialize(&toastkey,
|
||||
(bits16) 0,
|
||||
(AttrNumber) 1,
|
||||
(RegProcedure) F_OIDEQ,
|
||||
ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
|
||||
(bits16) 0,
|
||||
(AttrNumber) 1,
|
||||
(RegProcedure) F_OIDEQ,
|
||||
ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
|
||||
|
||||
/* ----------
|
||||
* Read the chunks by index
|
||||
@ -961,36 +969,36 @@ toast_delete_datum(Relation rel, Datum value)
|
||||
static varattrib *
|
||||
toast_fetch_datum(varattrib *attr)
|
||||
{
|
||||
Relation toastrel;
|
||||
Relation toastidx;
|
||||
ScanKeyData toastkey;
|
||||
IndexScanDesc toastscan;
|
||||
HeapTupleData toasttup;
|
||||
HeapTuple ttup;
|
||||
TupleDesc toasttupDesc;
|
||||
RetrieveIndexResult indexRes;
|
||||
Buffer buffer;
|
||||
Relation toastrel;
|
||||
Relation toastidx;
|
||||
ScanKeyData toastkey;
|
||||
IndexScanDesc toastscan;
|
||||
HeapTupleData toasttup;
|
||||
HeapTuple ttup;
|
||||
TupleDesc toasttupDesc;
|
||||
RetrieveIndexResult indexRes;
|
||||
Buffer buffer;
|
||||
|
||||
varattrib *result;
|
||||
int32 ressize;
|
||||
int32 residx;
|
||||
int numchunks;
|
||||
Pointer chunk;
|
||||
bool isnull;
|
||||
int32 chunksize;
|
||||
varattrib *result;
|
||||
int32 ressize;
|
||||
int32 residx;
|
||||
int numchunks;
|
||||
Pointer chunk;
|
||||
bool isnull;
|
||||
int32 chunksize;
|
||||
|
||||
char *chunks_found;
|
||||
char *chunks_expected;
|
||||
char *chunks_found;
|
||||
char *chunks_expected;
|
||||
|
||||
ressize = attr->va_content.va_external.va_extsize;
|
||||
numchunks = ((ressize - 1) / TOAST_MAX_CHUNK_SIZE) + 1;
|
||||
numchunks = ((ressize - 1) / TOAST_MAX_CHUNK_SIZE) + 1;
|
||||
|
||||
chunks_found = palloc(numchunks);
|
||||
chunks_found = palloc(numchunks);
|
||||
chunks_expected = palloc(numchunks);
|
||||
memset(chunks_found, 0, numchunks);
|
||||
memset(chunks_found, 0, numchunks);
|
||||
memset(chunks_expected, 1, numchunks);
|
||||
|
||||
result = (varattrib *)palloc(ressize + VARHDRSZ);
|
||||
result = (varattrib *) palloc(ressize + VARHDRSZ);
|
||||
VARATT_SIZEP(result) = ressize + VARHDRSZ;
|
||||
if (VARATT_IS_COMPRESSED(attr))
|
||||
VARATT_SIZEP(result) |= VARATT_FLAG_COMPRESSED;
|
||||
@ -999,8 +1007,8 @@ toast_fetch_datum(varattrib *attr)
|
||||
* Open the toast relation and it's index
|
||||
* ----------
|
||||
*/
|
||||
toastrel = heap_open(attr->va_content.va_external.va_toastrelid,
|
||||
AccessShareLock);
|
||||
toastrel = heap_open(attr->va_content.va_external.va_toastrelid,
|
||||
AccessShareLock);
|
||||
toasttupDesc = toastrel->rd_att;
|
||||
toastidx = index_open(attr->va_content.va_external.va_toastidxid);
|
||||
|
||||
@ -1009,10 +1017,10 @@ toast_fetch_datum(varattrib *attr)
|
||||
* ----------
|
||||
*/
|
||||
ScanKeyEntryInitialize(&toastkey,
|
||||
(bits16) 0,
|
||||
(AttrNumber) 1,
|
||||
(RegProcedure) F_OIDEQ,
|
||||
ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
|
||||
(bits16) 0,
|
||||
(AttrNumber) 1,
|
||||
(RegProcedure) F_OIDEQ,
|
||||
ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
|
||||
|
||||
/* ----------
|
||||
* Read the chunks by index
|
||||
@ -1049,7 +1057,7 @@ toast_fetch_datum(varattrib *attr)
|
||||
elog(ERROR, "unexpected chunk number %d for toast value %d",
|
||||
residx,
|
||||
attr->va_content.va_external.va_valueid);
|
||||
if (residx < numchunks-1)
|
||||
if (residx < numchunks - 1)
|
||||
{
|
||||
if (chunksize != TOAST_MAX_CHUNK_SIZE)
|
||||
elog(ERROR, "unexpected chunk size %d in chunk %d for toast value %d",
|
||||
@ -1072,7 +1080,7 @@ toast_fetch_datum(varattrib *attr)
|
||||
* Copy the data into proper place in our result
|
||||
* ----------
|
||||
*/
|
||||
memcpy(((char *)VARATT_DATA(result)) + residx * TOAST_MAX_CHUNK_SIZE,
|
||||
memcpy(((char *) VARATT_DATA(result)) + residx * TOAST_MAX_CHUNK_SIZE,
|
||||
VARATT_DATA(chunk),
|
||||
chunksize);
|
||||
|
||||
@ -1085,7 +1093,7 @@ toast_fetch_datum(varattrib *attr)
|
||||
*/
|
||||
if (memcmp(chunks_found, chunks_expected, numchunks) != 0)
|
||||
elog(ERROR, "not all toast chunks found for value %d",
|
||||
attr->va_content.va_external.va_valueid);
|
||||
attr->va_content.va_external.va_valueid);
|
||||
pfree(chunks_expected);
|
||||
pfree(chunks_found);
|
||||
|
||||
|
Reference in New Issue
Block a user