mirror of
https://github.com/postgres/postgres.git
synced 2025-07-23 03:21:12 +03:00
Remove dashes in comments that don't need them, rewrap with pgindent.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.111 2001/03/22 03:59:13 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.112 2001/03/22 06:16:07 momjian Exp $
|
||||
*
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
@ -116,20 +116,20 @@ initscan(HeapScanDesc scan,
|
||||
unsigned nkeys,
|
||||
ScanKey key)
|
||||
{
|
||||
/* ----------------
|
||||
* Make sure we have up-to-date idea of number of blocks in relation.
|
||||
* It is sufficient to do this once at scan start, since any tuples
|
||||
* added while the scan is in progress will be invisible to my
|
||||
* transaction anyway...
|
||||
* ----------------
|
||||
|
||||
/*
|
||||
* Make sure we have up-to-date idea of number of blocks in relation.
|
||||
* It is sufficient to do this once at scan start, since any tuples
|
||||
* added while the scan is in progress will be invisible to my
|
||||
* transaction anyway...
|
||||
*/
|
||||
relation->rd_nblocks = RelationGetNumberOfBlocks(relation);
|
||||
|
||||
if (relation->rd_nblocks == 0)
|
||||
{
|
||||
/* ----------------
|
||||
* relation is empty
|
||||
* ----------------
|
||||
|
||||
/*
|
||||
* relation is empty
|
||||
*/
|
||||
scan->rs_ntup.t_datamcxt = scan->rs_ctup.t_datamcxt =
|
||||
scan->rs_ptup.t_datamcxt = NULL;
|
||||
@ -139,9 +139,9 @@ initscan(HeapScanDesc scan,
|
||||
}
|
||||
else if (atend)
|
||||
{
|
||||
/* ----------------
|
||||
* reverse scan
|
||||
* ----------------
|
||||
|
||||
/*
|
||||
* reverse scan
|
||||
*/
|
||||
scan->rs_ntup.t_datamcxt = scan->rs_ctup.t_datamcxt = NULL;
|
||||
scan->rs_ntup.t_data = scan->rs_ctup.t_data = NULL;
|
||||
@ -152,9 +152,9 @@ initscan(HeapScanDesc scan,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ----------------
|
||||
* forward scan
|
||||
* ----------------
|
||||
|
||||
/*
|
||||
* forward scan
|
||||
*/
|
||||
scan->rs_ctup.t_datamcxt = scan->rs_ptup.t_datamcxt = NULL;
|
||||
scan->rs_ctup.t_data = scan->rs_ptup.t_data = NULL;
|
||||
@ -170,9 +170,8 @@ initscan(HeapScanDesc scan,
|
||||
ItemPointerSetInvalid(&(scan->rs_mntid));
|
||||
ItemPointerSetInvalid(&(scan->rs_mcd));
|
||||
|
||||
/* ----------------
|
||||
* copy the scan key, if appropriate
|
||||
* ----------------
|
||||
/*
|
||||
* copy the scan key, if appropriate
|
||||
*/
|
||||
if (key != NULL)
|
||||
memmove(scan->rs_key, key, nkeys * sizeof(ScanKeyData));
|
||||
@ -188,11 +187,9 @@ unpinscan(HeapScanDesc scan)
|
||||
if (BufferIsValid(scan->rs_pbuf))
|
||||
ReleaseBuffer(scan->rs_pbuf);
|
||||
|
||||
/* ------------------------------------
|
||||
* Scan will pin buffer once for each non-NULL tuple pointer
|
||||
* (ptup, ctup, ntup), so they have to be unpinned multiple
|
||||
* times.
|
||||
* ------------------------------------
|
||||
/*
|
||||
* Scan will pin buffer once for each non-NULL tuple pointer (ptup,
|
||||
* ctup, ntup), so they have to be unpinned multiple times.
|
||||
*/
|
||||
if (BufferIsValid(scan->rs_cbuf))
|
||||
ReleaseBuffer(scan->rs_cbuf);
|
||||
@ -251,19 +248,17 @@ heapgettup(Relation relation,
|
||||
ItemPointer tid = (tuple->t_data == NULL) ?
|
||||
(ItemPointer) NULL : &(tuple->t_self);
|
||||
|
||||
/* ----------------
|
||||
* increment access statistics
|
||||
* ----------------
|
||||
/*
|
||||
* increment access statistics
|
||||
*/
|
||||
IncrHeapAccessStat(local_heapgettup);
|
||||
IncrHeapAccessStat(global_heapgettup);
|
||||
|
||||
/* ----------------
|
||||
* debugging stuff
|
||||
/*
|
||||
* debugging stuff
|
||||
*
|
||||
* check validity of arguments, here and for other functions too
|
||||
* Note: no locking manipulations needed--this is a local function
|
||||
* ----------------
|
||||
* check validity of arguments, here and for other functions too Note: no
|
||||
* locking manipulations needed--this is a local function
|
||||
*/
|
||||
#ifdef HEAPDEBUGALL
|
||||
if (ItemPointerIsValid(tid))
|
||||
@ -289,9 +284,8 @@ heapgettup(Relation relation,
|
||||
|
||||
tuple->t_tableOid = relation->rd_id;
|
||||
|
||||
/* ----------------
|
||||
* return null immediately if relation is empty
|
||||
* ----------------
|
||||
/*
|
||||
* return null immediately if relation is empty
|
||||
*/
|
||||
if (!(pages = relation->rd_nblocks))
|
||||
{
|
||||
@ -300,15 +294,14 @@ heapgettup(Relation relation,
|
||||
return;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* calculate next starting lineoff, given scan direction
|
||||
* ----------------
|
||||
/*
|
||||
* calculate next starting lineoff, given scan direction
|
||||
*/
|
||||
if (!dir)
|
||||
{
|
||||
/* ----------------
|
||||
|
||||
/*
|
||||
* ``no movement'' scan direction
|
||||
* ----------------
|
||||
*/
|
||||
/* assume it is a valid TID XXX */
|
||||
if (ItemPointerIsValid(tid) == false)
|
||||
@ -340,9 +333,9 @@ heapgettup(Relation relation,
|
||||
}
|
||||
else if (dir < 0)
|
||||
{
|
||||
/* ----------------
|
||||
* reverse scan direction
|
||||
* ----------------
|
||||
|
||||
/*
|
||||
* reverse scan direction
|
||||
*/
|
||||
if (ItemPointerIsValid(tid) == false)
|
||||
tid = NULL;
|
||||
@ -383,9 +376,9 @@ heapgettup(Relation relation,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ----------------
|
||||
* forward scan direction
|
||||
* ----------------
|
||||
|
||||
/*
|
||||
* forward scan direction
|
||||
*/
|
||||
if (ItemPointerIsValid(tid) == false)
|
||||
{
|
||||
@ -420,10 +413,9 @@ heapgettup(Relation relation,
|
||||
|
||||
/* 'dir' is now non-zero */
|
||||
|
||||
/* ----------------
|
||||
* calculate line pointer and number of remaining items
|
||||
* to check on this page.
|
||||
* ----------------
|
||||
/*
|
||||
* calculate line pointer and number of remaining items to check on
|
||||
* this page.
|
||||
*/
|
||||
lpp = PageGetItemId(dp, lineoff);
|
||||
if (dir < 0)
|
||||
@ -431,10 +423,9 @@ heapgettup(Relation relation,
|
||||
else
|
||||
linesleft = lines - lineoff;
|
||||
|
||||
/* ----------------
|
||||
* advance the scan until we find a qualifying tuple or
|
||||
* run out of stuff to scan
|
||||
* ----------------
|
||||
/*
|
||||
* advance the scan until we find a qualifying tuple or run out of
|
||||
* stuff to scan
|
||||
*/
|
||||
for (;;)
|
||||
{
|
||||
@ -446,9 +437,9 @@ heapgettup(Relation relation,
|
||||
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.
|
||||
* ----------------
|
||||
|
||||
/*
|
||||
* if current tuple qualifies, return it.
|
||||
*/
|
||||
HeapTupleSatisfies(tuple, relation, *buffer, (PageHeader) dp,
|
||||
snapshot, nkeys, key);
|
||||
@ -459,9 +450,8 @@ heapgettup(Relation relation,
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* otherwise move to the next item on the page
|
||||
* ----------------
|
||||
/*
|
||||
* otherwise move to the next item on the page
|
||||
*/
|
||||
--linesleft;
|
||||
if (dir < 0)
|
||||
@ -477,17 +467,15 @@ heapgettup(Relation relation,
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* if we get here, it means we've exhausted the items on
|
||||
* this page and it's time to move to the next..
|
||||
* ----------------
|
||||
/*
|
||||
* if we get here, it means we've exhausted the items on this page
|
||||
* and it's time to move to the next..
|
||||
*/
|
||||
LockBuffer(*buffer, BUFFER_LOCK_UNLOCK);
|
||||
page = nextpage(page, dir);
|
||||
|
||||
/* ----------------
|
||||
* return NULL if we've exhausted all the pages..
|
||||
* ----------------
|
||||
/*
|
||||
* return NULL if we've exhausted all the pages..
|
||||
*/
|
||||
if (page < 0 || page >= pages)
|
||||
{
|
||||
@ -588,9 +576,8 @@ heap_open(Oid relationId, LOCKMODE lockmode)
|
||||
|
||||
Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
|
||||
|
||||
/* ----------------
|
||||
* increment access statistics
|
||||
* ----------------
|
||||
/*
|
||||
* increment access statistics
|
||||
*/
|
||||
IncrHeapAccessStat(local_open);
|
||||
IncrHeapAccessStat(global_open);
|
||||
@ -626,9 +613,8 @@ heap_openr(const char *relationName, LOCKMODE lockmode)
|
||||
|
||||
Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
|
||||
|
||||
/* ----------------
|
||||
* increment access statistics
|
||||
* ----------------
|
||||
/*
|
||||
* increment access statistics
|
||||
*/
|
||||
IncrHeapAccessStat(local_openr);
|
||||
IncrHeapAccessStat(global_openr);
|
||||
@ -663,9 +649,8 @@ heap_open_nofail(Oid relationId)
|
||||
{
|
||||
Relation r;
|
||||
|
||||
/* ----------------
|
||||
* increment access statistics
|
||||
* ----------------
|
||||
/*
|
||||
* increment access statistics
|
||||
*/
|
||||
IncrHeapAccessStat(local_open);
|
||||
IncrHeapAccessStat(global_open);
|
||||
@ -694,9 +679,8 @@ heap_openr_nofail(const char *relationName)
|
||||
{
|
||||
Relation r;
|
||||
|
||||
/* ----------------
|
||||
* increment access statistics
|
||||
* ----------------
|
||||
/*
|
||||
* increment access statistics
|
||||
*/
|
||||
IncrHeapAccessStat(local_openr);
|
||||
IncrHeapAccessStat(global_openr);
|
||||
@ -724,9 +708,8 @@ heap_close(Relation relation, LOCKMODE lockmode)
|
||||
{
|
||||
Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
|
||||
|
||||
/* ----------------
|
||||
* increment access statistics
|
||||
* ----------------
|
||||
/*
|
||||
* increment access statistics
|
||||
*/
|
||||
IncrHeapAccessStat(local_close);
|
||||
IncrHeapAccessStat(global_close);
|
||||
@ -752,27 +735,24 @@ heap_beginscan(Relation relation,
|
||||
{
|
||||
HeapScanDesc scan;
|
||||
|
||||
/* ----------------
|
||||
* increment access statistics
|
||||
* ----------------
|
||||
/*
|
||||
* increment access statistics
|
||||
*/
|
||||
IncrHeapAccessStat(local_beginscan);
|
||||
IncrHeapAccessStat(global_beginscan);
|
||||
|
||||
/* ----------------
|
||||
* sanity checks
|
||||
* ----------------
|
||||
/*
|
||||
* sanity checks
|
||||
*/
|
||||
if (!RelationIsValid(relation))
|
||||
elog(ERROR, "heap_beginscan: !RelationIsValid(relation)");
|
||||
|
||||
/* ----------------
|
||||
* increment relation ref count while scanning relation
|
||||
/*
|
||||
* increment relation ref count while scanning relation
|
||||
*
|
||||
* This is just to make really sure the relcache entry won't go away
|
||||
* while the scan has a pointer to it. Caller should be holding the
|
||||
* rel open anyway, so this is redundant in all normal scenarios...
|
||||
* ----------------
|
||||
* This is just to make really sure the relcache entry won't go away
|
||||
* while the scan has a pointer to it. Caller should be holding the
|
||||
* rel open anyway, so this is redundant in all normal scenarios...
|
||||
*/
|
||||
RelationIncrementReferenceCount(relation);
|
||||
|
||||
@ -780,9 +760,8 @@ heap_beginscan(Relation relation,
|
||||
if (relation->rd_rel->relkind == RELKIND_UNCATALOGED)
|
||||
snapshot = SnapshotSelf;
|
||||
|
||||
/* ----------------
|
||||
* allocate and initialize scan descriptor
|
||||
* ----------------
|
||||
/*
|
||||
* allocate and initialize scan descriptor
|
||||
*/
|
||||
scan = (HeapScanDesc) palloc(sizeof(HeapScanDescData));
|
||||
|
||||
@ -814,22 +793,20 @@ heap_rescan(HeapScanDesc scan,
|
||||
bool scanFromEnd,
|
||||
ScanKey key)
|
||||
{
|
||||
/* ----------------
|
||||
* increment access statistics
|
||||
* ----------------
|
||||
|
||||
/*
|
||||
* increment access statistics
|
||||
*/
|
||||
IncrHeapAccessStat(local_rescan);
|
||||
IncrHeapAccessStat(global_rescan);
|
||||
|
||||
/* ----------------
|
||||
* unpin scan buffers
|
||||
* ----------------
|
||||
/*
|
||||
* unpin scan buffers
|
||||
*/
|
||||
unpinscan(scan);
|
||||
|
||||
/* ----------------
|
||||
* reinitialize scan descriptor
|
||||
* ----------------
|
||||
/*
|
||||
* reinitialize scan descriptor
|
||||
*/
|
||||
scan->rs_atend = scanFromEnd;
|
||||
initscan(scan, scan->rs_rd, scanFromEnd, scan->rs_nkeys, key);
|
||||
@ -845,24 +822,22 @@ heap_rescan(HeapScanDesc scan,
|
||||
void
|
||||
heap_endscan(HeapScanDesc scan)
|
||||
{
|
||||
/* ----------------
|
||||
* increment access statistics
|
||||
* ----------------
|
||||
|
||||
/*
|
||||
* increment access statistics
|
||||
*/
|
||||
IncrHeapAccessStat(local_endscan);
|
||||
IncrHeapAccessStat(global_endscan);
|
||||
|
||||
/* Note: no locking manipulations needed */
|
||||
|
||||
/* ----------------
|
||||
* unpin scan buffers
|
||||
* ----------------
|
||||
/*
|
||||
* unpin scan buffers
|
||||
*/
|
||||
unpinscan(scan);
|
||||
|
||||
/* ----------------
|
||||
* decrement relation reference count and free scan descriptor storage
|
||||
* ----------------
|
||||
/*
|
||||
* decrement relation reference count and free scan descriptor storage
|
||||
*/
|
||||
RelationDecrementReferenceCount(scan->rs_rd);
|
||||
|
||||
@ -919,34 +894,31 @@ heap_getnext(HeapScanDesc scandesc, int backw)
|
||||
{
|
||||
HeapScanDesc scan = scandesc;
|
||||
|
||||
/* ----------------
|
||||
* increment access statistics
|
||||
* ----------------
|
||||
/*
|
||||
* increment access statistics
|
||||
*/
|
||||
IncrHeapAccessStat(local_getnext);
|
||||
IncrHeapAccessStat(global_getnext);
|
||||
|
||||
/* Note: no locking manipulations needed */
|
||||
|
||||
/* ----------------
|
||||
* argument checks
|
||||
* ----------------
|
||||
/*
|
||||
* argument checks
|
||||
*/
|
||||
if (scan == NULL)
|
||||
elog(ERROR, "heap_getnext: NULL relscan");
|
||||
|
||||
/* ----------------
|
||||
* initialize return buffer to InvalidBuffer
|
||||
* ----------------
|
||||
/*
|
||||
* initialize return buffer to InvalidBuffer
|
||||
*/
|
||||
|
||||
HEAPDEBUG_1; /* heap_getnext( info ) */
|
||||
|
||||
if (backw)
|
||||
{
|
||||
/* ----------------
|
||||
* handle reverse scan
|
||||
* ----------------
|
||||
|
||||
/*
|
||||
* handle reverse scan
|
||||
*/
|
||||
HEAPDEBUG_2; /* heap_getnext called with backw */
|
||||
|
||||
@ -1020,9 +992,9 @@ heap_getnext(HeapScanDesc scandesc, int backw)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ----------------
|
||||
* handle forward scan
|
||||
* ----------------
|
||||
|
||||
/*
|
||||
* handle forward scan
|
||||
*/
|
||||
if (scan->rs_ctup.t_data == scan->rs_ntup.t_data &&
|
||||
BufferIsInvalid(scan->rs_nbuf))
|
||||
@ -1097,10 +1069,9 @@ heap_getnext(HeapScanDesc scandesc, int backw)
|
||||
scan->rs_nbuf = UnknownBuffer;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* if we get here it means we have a new current scan tuple, so
|
||||
* point to the proper return buffer and return the tuple.
|
||||
* ----------------
|
||||
/*
|
||||
* if we get here it means we have a new current scan tuple, so point
|
||||
* to the proper return buffer and return the tuple.
|
||||
*/
|
||||
|
||||
HEAPDEBUG_7; /* heap_getnext returning tuple */
|
||||
@ -1133,17 +1104,15 @@ heap_fetch(Relation relation,
|
||||
ItemPointer tid = &(tuple->t_self);
|
||||
OffsetNumber offnum;
|
||||
|
||||
/* ----------------
|
||||
* increment access statistics
|
||||
* ----------------
|
||||
/*
|
||||
* increment access statistics
|
||||
*/
|
||||
IncrHeapAccessStat(local_fetch);
|
||||
IncrHeapAccessStat(global_fetch);
|
||||
|
||||
/* ----------------
|
||||
* get the buffer from the relation descriptor
|
||||
* Note that this does a buffer pin.
|
||||
* ----------------
|
||||
/*
|
||||
* get the buffer from the relation descriptor Note that this does a
|
||||
* buffer pin.
|
||||
*/
|
||||
|
||||
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
|
||||
@ -1154,17 +1123,15 @@ heap_fetch(Relation relation,
|
||||
|
||||
LockBuffer(buffer, BUFFER_LOCK_SHARE);
|
||||
|
||||
/* ----------------
|
||||
* get the item line pointer corresponding to the requested tid
|
||||
* ----------------
|
||||
/*
|
||||
* get the item line pointer corresponding to the requested tid
|
||||
*/
|
||||
dp = (PageHeader) BufferGetPage(buffer);
|
||||
offnum = ItemPointerGetOffsetNumber(tid);
|
||||
lp = PageGetItemId(dp, offnum);
|
||||
|
||||
/* ----------------
|
||||
* more sanity checks
|
||||
* ----------------
|
||||
/*
|
||||
* more sanity checks
|
||||
*/
|
||||
|
||||
if (!ItemIdIsUsed(lp))
|
||||
@ -1182,9 +1149,8 @@ heap_fetch(Relation relation,
|
||||
tuple->t_len = ItemIdGetLength(lp);
|
||||
tuple->t_tableOid = relation->rd_id;
|
||||
|
||||
/* ----------------
|
||||
* check time qualification of tid
|
||||
* ----------------
|
||||
/*
|
||||
* check time qualification of tid
|
||||
*/
|
||||
|
||||
HeapTupleSatisfies(tuple, relation, buffer, dp,
|
||||
@ -1229,10 +1195,9 @@ heap_get_latest_tid(Relation relation,
|
||||
bool invalidBlock,
|
||||
linkend;
|
||||
|
||||
/* ----------------
|
||||
* get the buffer from the relation descriptor
|
||||
* Note that this does a buffer pin.
|
||||
* ----------------
|
||||
/*
|
||||
* get the buffer from the relation descriptor Note that this does a
|
||||
* buffer pin.
|
||||
*/
|
||||
|
||||
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
|
||||
@ -1243,9 +1208,8 @@ heap_get_latest_tid(Relation relation,
|
||||
|
||||
LockBuffer(buffer, BUFFER_LOCK_SHARE);
|
||||
|
||||
/* ----------------
|
||||
* get the item line pointer corresponding to the requested tid
|
||||
* ----------------
|
||||
/*
|
||||
* get the item line pointer corresponding to the requested tid
|
||||
*/
|
||||
dp = (PageHeader) BufferGetPage(buffer);
|
||||
offnum = ItemPointerGetOffsetNumber(tid);
|
||||
@ -1263,9 +1227,8 @@ heap_get_latest_tid(Relation relation,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* more sanity checks
|
||||
* ----------------
|
||||
/*
|
||||
* more sanity checks
|
||||
*/
|
||||
|
||||
tp.t_datamcxt = NULL;
|
||||
@ -1274,9 +1237,8 @@ heap_get_latest_tid(Relation relation,
|
||||
tp.t_self = *tid;
|
||||
ctid = tp.t_data->t_ctid;
|
||||
|
||||
/* ----------------
|
||||
* check time qualification of tid
|
||||
* ----------------
|
||||
/*
|
||||
* check time qualification of tid
|
||||
*/
|
||||
|
||||
HeapTupleSatisfies(&tp, relation, buffer, dp,
|
||||
@ -1323,15 +1285,13 @@ heap_insert(Relation relation, HeapTuple tup)
|
||||
IncrHeapAccessStat(local_insert);
|
||||
IncrHeapAccessStat(global_insert);
|
||||
|
||||
/* ----------------
|
||||
* If the object id of this tuple has already been assigned, trust
|
||||
* the caller. There are a couple of ways this can happen. At initial
|
||||
* db creation, the backend program sets oids for tuples. When we
|
||||
* define an index, we set the oid. Finally, in the future, we may
|
||||
* allow users to set their own object ids in order to support a
|
||||
* persistent object store (objects need to contain pointers to one
|
||||
* another).
|
||||
* ----------------
|
||||
/*
|
||||
* If the object id of this tuple has already been assigned, trust the
|
||||
* caller. There are a couple of ways this can happen. At initial db
|
||||
* creation, the backend program sets oids for tuples. When we define
|
||||
* an index, we set the oid. Finally, in the future, we may allow
|
||||
* users to set their own object ids in order to support a persistent
|
||||
* object store (objects need to contain pointers to one another).
|
||||
*/
|
||||
if (!OidIsValid(tup->t_data->t_oid))
|
||||
tup->t_data->t_oid = newoid();
|
||||
@ -1346,10 +1306,10 @@ heap_insert(Relation relation, HeapTuple tup)
|
||||
tup->t_tableOid = relation->rd_id;
|
||||
|
||||
#ifdef TUPLE_TOASTER_ACTIVE
|
||||
/* ----------
|
||||
* If the new tuple is too big for storage or contains already
|
||||
* toasted attributes from some other relation, invoke the toaster.
|
||||
* ----------
|
||||
|
||||
/*
|
||||
* If the new tuple is too big for storage or contains already toasted
|
||||
* attributes from some other relation, invoke the toaster.
|
||||
*/
|
||||
if (HeapTupleHasExtended(tup) ||
|
||||
(MAXALIGN(tup->t_len) > TOAST_TUPLE_THRESHOLD))
|
||||
@ -1540,12 +1500,12 @@ l1:
|
||||
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
|
||||
|
||||
#ifdef TUPLE_TOASTER_ACTIVE
|
||||
/* ----------
|
||||
* If the relation has toastable attributes, we need to delete
|
||||
* no longer needed items there too. We have to do this before
|
||||
|
||||
/*
|
||||
* If the relation has toastable attributes, we need to delete no
|
||||
* longer needed items there too. We have to do this before
|
||||
* WriteBuffer because we need to look at the contents of the tuple,
|
||||
* but it's OK to release the context lock on the buffer first.
|
||||
* ----------
|
||||
*/
|
||||
if (HeapTupleHasExtended(&tp))
|
||||
heap_tuple_toast_attrs(relation, NULL, &(tp));
|
||||
@ -1977,9 +1937,8 @@ void
|
||||
heap_markpos(HeapScanDesc scan)
|
||||
{
|
||||
|
||||
/* ----------------
|
||||
* increment access statistics
|
||||
* ----------------
|
||||
/*
|
||||
* increment access statistics
|
||||
*/
|
||||
IncrHeapAccessStat(local_markpos);
|
||||
IncrHeapAccessStat(global_markpos);
|
||||
@ -2012,9 +1971,8 @@ heap_markpos(HeapScanDesc scan)
|
||||
scan->rs_key);
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
/*
|
||||
* Should not unpin the buffer pages. They may still be in use.
|
||||
* ----------------
|
||||
*/
|
||||
if (scan->rs_ptup.t_data != NULL)
|
||||
scan->rs_mptid = scan->rs_ptup.t_self;
|
||||
@ -2054,9 +2012,9 @@ heap_markpos(HeapScanDesc scan)
|
||||
void
|
||||
heap_restrpos(HeapScanDesc scan)
|
||||
{
|
||||
/* ----------------
|
||||
* increment access statistics
|
||||
* ----------------
|
||||
|
||||
/*
|
||||
* increment access statistics
|
||||
*/
|
||||
IncrHeapAccessStat(local_restrpos);
|
||||
IncrHeapAccessStat(global_restrpos);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Id: hio.c,v 1.36 2001/03/22 03:59:13 momjian Exp $
|
||||
* $Id: hio.c,v 1.37 2001/03/22 06:16:07 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -37,9 +37,8 @@ RelationPutHeapTuple(Relation relation,
|
||||
ItemId itemId;
|
||||
Item item;
|
||||
|
||||
/* ----------------
|
||||
* increment access statistics
|
||||
* ----------------
|
||||
/*
|
||||
* increment access statistics
|
||||
*/
|
||||
IncrHeapAccessStat(local_RelationPutHeapTuple);
|
||||
IncrHeapAccessStat(global_RelationPutHeapTuple);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/Attic/stats.c,v 1.23 2001/01/24 19:42:48 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/Attic/stats.c,v 1.24 2001/03/22 06:16:07 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* initam should be moved someplace else.
|
||||
@ -37,25 +37,22 @@ InitHeapAccessStatistics()
|
||||
MemoryContext oldContext;
|
||||
HeapAccessStatistics stats;
|
||||
|
||||
/* ----------------
|
||||
* make sure we don't initialize things twice
|
||||
* ----------------
|
||||
/*
|
||||
* make sure we don't initialize things twice
|
||||
*/
|
||||
if (heap_access_stats != NULL)
|
||||
return;
|
||||
|
||||
/* ----------------
|
||||
* allocate statistics structure from the top memory context
|
||||
* ----------------
|
||||
/*
|
||||
* allocate statistics structure from the top memory context
|
||||
*/
|
||||
oldContext = MemoryContextSwitchTo(TopMemoryContext);
|
||||
|
||||
stats = (HeapAccessStatistics)
|
||||
palloc(sizeof(HeapAccessStatisticsData));
|
||||
|
||||
/* ----------------
|
||||
* initialize fields to default values
|
||||
* ----------------
|
||||
/*
|
||||
* initialize fields to default values
|
||||
*/
|
||||
stats->global_open = 0;
|
||||
stats->global_openr = 0;
|
||||
@ -103,17 +100,15 @@ InitHeapAccessStatistics()
|
||||
stats->local_RelationNameGetRelation = 0;
|
||||
stats->global_RelationNameGetRelation = 0;
|
||||
|
||||
/* ----------------
|
||||
* record init times
|
||||
* ----------------
|
||||
/*
|
||||
* record init times
|
||||
*/
|
||||
time(&stats->init_global_timestamp);
|
||||
time(&stats->local_reset_timestamp);
|
||||
time(&stats->last_request_timestamp);
|
||||
|
||||
/* ----------------
|
||||
* return to old memory context
|
||||
* ----------------
|
||||
/*
|
||||
* return to old memory context
|
||||
*/
|
||||
MemoryContextSwitchTo(oldContext);
|
||||
|
||||
@ -130,18 +125,16 @@ ResetHeapAccessStatistics()
|
||||
{
|
||||
HeapAccessStatistics stats;
|
||||
|
||||
/* ----------------
|
||||
* do nothing if stats aren't initialized
|
||||
* ----------------
|
||||
/*
|
||||
* do nothing if stats aren't initialized
|
||||
*/
|
||||
if (heap_access_stats == NULL)
|
||||
return;
|
||||
|
||||
stats = heap_access_stats;
|
||||
|
||||
/* ----------------
|
||||
* reset local counts
|
||||
* ----------------
|
||||
/*
|
||||
* reset local counts
|
||||
*/
|
||||
stats->local_open = 0;
|
||||
stats->local_openr = 0;
|
||||
@ -165,9 +158,8 @@ ResetHeapAccessStatistics()
|
||||
stats->local_RelationPutHeapTuple = 0;
|
||||
stats->local_RelationPutLongHeapTuple = 0;
|
||||
|
||||
/* ----------------
|
||||
* reset local timestamps
|
||||
* ----------------
|
||||
/*
|
||||
* reset local timestamps
|
||||
*/
|
||||
time(&stats->local_reset_timestamp);
|
||||
time(&stats->last_request_timestamp);
|
||||
@ -185,22 +177,19 @@ GetHeapAccessStatistics()
|
||||
{
|
||||
HeapAccessStatistics stats;
|
||||
|
||||
/* ----------------
|
||||
* return nothing if stats aren't initialized
|
||||
* ----------------
|
||||
/*
|
||||
* return nothing if stats aren't initialized
|
||||
*/
|
||||
if (heap_access_stats == NULL)
|
||||
return NULL;
|
||||
|
||||
/* ----------------
|
||||
* record the current request time
|
||||
* ----------------
|
||||
/*
|
||||
* record the current request time
|
||||
*/
|
||||
time(&heap_access_stats->last_request_timestamp);
|
||||
|
||||
/* ----------------
|
||||
* allocate a copy of the stats and return it to the caller.
|
||||
* ----------------
|
||||
/*
|
||||
* allocate a copy of the stats and return it to the caller.
|
||||
*/
|
||||
stats = (HeapAccessStatistics)
|
||||
palloc(sizeof(HeapAccessStatisticsData));
|
||||
@ -222,9 +211,9 @@ GetHeapAccessStatistics()
|
||||
void
|
||||
PrintHeapAccessStatistics(HeapAccessStatistics stats)
|
||||
{
|
||||
/* ----------------
|
||||
* return nothing if stats aren't valid
|
||||
* ----------------
|
||||
|
||||
/*
|
||||
* return nothing if stats aren't valid
|
||||
*/
|
||||
if (stats == NULL)
|
||||
return;
|
||||
@ -342,9 +331,9 @@ PrintAndFreeHeapAccessStatistics(HeapAccessStatistics stats)
|
||||
void
|
||||
initam(void)
|
||||
{
|
||||
/* ----------------
|
||||
* initialize heap statistics.
|
||||
* ----------------
|
||||
|
||||
/*
|
||||
* initialize heap statistics.
|
||||
*/
|
||||
InitHeapAccessStatistics();
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.18 2001/03/22 03:59:13 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.19 2001/03/22 06:16:07 momjian Exp $
|
||||
*
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
@ -81,17 +81,18 @@ heap_tuple_fetch_attr(varattrib *attr)
|
||||
|
||||
if (VARATT_IS_EXTERNAL(attr))
|
||||
{
|
||||
/* ----------
|
||||
|
||||
/*
|
||||
* This is an external stored plain value
|
||||
* ----------
|
||||
*/
|
||||
result = toast_fetch_datum(attr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ----------
|
||||
* This is a plain value inside of the main tuple - why am I called?
|
||||
* ----------
|
||||
|
||||
/*
|
||||
* This is a plain value inside of the main tuple - why am I
|
||||
* called?
|
||||
*/
|
||||
result = attr;
|
||||
}
|
||||
@ -134,18 +135,18 @@ heap_tuple_untoast_attr(varattrib *attr)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ----------
|
||||
|
||||
/*
|
||||
* This is an external stored plain value
|
||||
* ----------
|
||||
*/
|
||||
result = toast_fetch_datum(attr);
|
||||
}
|
||||
}
|
||||
else if (VARATT_IS_COMPRESSED(attr))
|
||||
{
|
||||
/* ----------
|
||||
|
||||
/*
|
||||
* This is a compressed value inside of the main tuple
|
||||
* ----------
|
||||
*/
|
||||
result = (varattrib *) palloc(attr->va_content.va_compressed.va_rawsize
|
||||
+ VARHDRSZ);
|
||||
@ -154,9 +155,10 @@ heap_tuple_untoast_attr(varattrib *attr)
|
||||
pglz_decompress((PGLZ_Header *) attr, VARATT_DATA(result));
|
||||
}
|
||||
else
|
||||
/* ----------
|
||||
* This is a plain value inside of the main tuple - why am I called?
|
||||
* ----------
|
||||
|
||||
/*
|
||||
* This is a plain value inside of the main tuple - why am I
|
||||
* called?
|
||||
*/
|
||||
return attr;
|
||||
|
||||
@ -180,19 +182,16 @@ toast_delete(Relation rel, HeapTuple oldtup)
|
||||
Datum value;
|
||||
bool isnull;
|
||||
|
||||
/* ----------
|
||||
* Get the tuple descriptor, the number of and attribute
|
||||
* descriptors.
|
||||
* ----------
|
||||
/*
|
||||
* Get the tuple descriptor, the number of and attribute descriptors.
|
||||
*/
|
||||
tupleDesc = rel->rd_att;
|
||||
numAttrs = tupleDesc->natts;
|
||||
att = tupleDesc->attrs;
|
||||
|
||||
/* ----------
|
||||
* Check for external stored attributes and delete them
|
||||
* from the secondary relation.
|
||||
* ----------
|
||||
/*
|
||||
* Check for external stored attributes and delete them from the
|
||||
* secondary relation.
|
||||
*/
|
||||
for (i = 0; i < numAttrs; i++)
|
||||
{
|
||||
@ -237,10 +236,9 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
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.
|
||||
* ----------
|
||||
/*
|
||||
* Get the tuple descriptor, the number of and attribute descriptors
|
||||
* and the location of the tuple values.
|
||||
*/
|
||||
tupleDesc = rel->rd_att;
|
||||
numAttrs = tupleDesc->natts;
|
||||
@ -266,9 +264,9 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
|
||||
if (oldtup != NULL)
|
||||
{
|
||||
/* ----------
|
||||
|
||||
/*
|
||||
* For UPDATE get the old and new values of this attribute
|
||||
* ----------
|
||||
*/
|
||||
old_value = (varattrib *) DatumGetPointer(
|
||||
heap_getattr(oldtup, i + 1, tupleDesc, &old_isnull));
|
||||
@ -276,10 +274,9 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
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 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))
|
||||
@ -290,21 +287,21 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
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
|
||||
* more after the update
|
||||
* ----------
|
||||
|
||||
/*
|
||||
* The old external store value isn't needed any more
|
||||
* after the update
|
||||
*/
|
||||
toast_delold[i] = true;
|
||||
need_delold = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ----------
|
||||
* This attribute isn't changed by this update
|
||||
* so we reuse the original reference to the old
|
||||
* value in the new tuple.
|
||||
* ----------
|
||||
|
||||
/*
|
||||
* This attribute isn't changed by this update so we
|
||||
* reuse the original reference to the old value in
|
||||
* the new tuple.
|
||||
*/
|
||||
toast_action[i] = 'p';
|
||||
toast_sizes[i] = VARATT_SIZE(toast_values[i]);
|
||||
@ -314,17 +311,16 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ----------
|
||||
|
||||
/*
|
||||
* For INSERT simply get the new value
|
||||
* ----------
|
||||
*/
|
||||
toast_values[i] =
|
||||
heap_getattr(newtup, i + 1, tupleDesc, &new_isnull);
|
||||
}
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Handle NULL attributes
|
||||
* ----------
|
||||
*/
|
||||
if (new_isnull)
|
||||
{
|
||||
@ -334,24 +330,22 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Now look at varsize attributes
|
||||
* ----------
|
||||
*/
|
||||
if (att[i]->attlen == -1)
|
||||
{
|
||||
/* ----------
|
||||
|
||||
/*
|
||||
* If the table's attribute says PLAIN always, force it so.
|
||||
* ----------
|
||||
*/
|
||||
if (att[i]->attstorage == 'p')
|
||||
toast_action[i] = 'p';
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* We took care of UPDATE above, so any external value we find
|
||||
* still in the tuple must be someone else's we cannot reuse.
|
||||
* Expand it to plain (and, probably, toast it again below).
|
||||
* ----------
|
||||
*/
|
||||
if (VARATT_IS_EXTERNAL(DatumGetPointer(toast_values[i])))
|
||||
{
|
||||
@ -362,17 +356,16 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
need_free = true;
|
||||
}
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Remember the size of this attribute
|
||||
* ----------
|
||||
*/
|
||||
toast_sizes[i] = VARATT_SIZE(DatumGetPointer(toast_values[i]));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ----------
|
||||
|
||||
/*
|
||||
* Not a variable size attribute, plain storage always
|
||||
* ----------
|
||||
*/
|
||||
toast_action[i] = 'p';
|
||||
toast_sizes[i] = att[i]->attlen;
|
||||
@ -393,9 +386,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
maxDataLen += BITMAPLEN(numAttrs);
|
||||
maxDataLen = TOAST_TUPLE_TARGET - MAXALIGN(maxDataLen);
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Look for attributes with attstorage 'x' to compress
|
||||
* ----------
|
||||
*/
|
||||
while (MAXALIGN(ComputeDataSize(tupleDesc, toast_values, toast_nulls)) >
|
||||
maxDataLen)
|
||||
@ -405,9 +397,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
Datum old_value;
|
||||
Datum new_value;
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Search for the biggest yet uncompressed internal attribute
|
||||
* ----------
|
||||
*/
|
||||
for (i = 0; i < numAttrs; i++)
|
||||
{
|
||||
@ -427,9 +418,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
if (biggest_attno < 0)
|
||||
break;
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Attempt to compress it inline
|
||||
* ----------
|
||||
*/
|
||||
i = biggest_attno;
|
||||
old_value = toast_values[i];
|
||||
@ -457,10 +447,9 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------
|
||||
* Second we look for attributes of attstorage 'x' or 'e' that
|
||||
* are still inline.
|
||||
* ----------
|
||||
/*
|
||||
* Second we look for attributes of attstorage 'x' or 'e' that are
|
||||
* still inline.
|
||||
*/
|
||||
while (MAXALIGN(ComputeDataSize(tupleDesc, toast_values, toast_nulls)) >
|
||||
maxDataLen && rel->rd_rel->reltoastrelid != InvalidOid)
|
||||
@ -469,10 +458,9 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
int32 biggest_size = MAXALIGN(sizeof(varattrib));
|
||||
Datum old_value;
|
||||
|
||||
/* ----------
|
||||
* Search for the biggest yet inlined attribute with
|
||||
* attstorage = 'x' or 'e'
|
||||
* ----------
|
||||
/*
|
||||
* Search for the biggest yet inlined attribute with attstorage =
|
||||
* 'x' or 'e'
|
||||
*/
|
||||
for (i = 0; i < numAttrs; i++)
|
||||
{
|
||||
@ -492,9 +480,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
if (biggest_attno < 0)
|
||||
break;
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Store this external
|
||||
* ----------
|
||||
*/
|
||||
i = biggest_attno;
|
||||
old_value = toast_values[i];
|
||||
@ -513,10 +500,9 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
need_free = true;
|
||||
}
|
||||
|
||||
/* ----------
|
||||
* Round 3 - this time we take attributes with storage
|
||||
* 'm' into compression
|
||||
* ----------
|
||||
/*
|
||||
* Round 3 - this time we take attributes with storage 'm' into
|
||||
* compression
|
||||
*/
|
||||
while (MAXALIGN(ComputeDataSize(tupleDesc, toast_values, toast_nulls)) >
|
||||
maxDataLen)
|
||||
@ -526,9 +512,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
Datum old_value;
|
||||
Datum new_value;
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Search for the biggest yet uncompressed internal attribute
|
||||
* ----------
|
||||
*/
|
||||
for (i = 0; i < numAttrs; i++)
|
||||
{
|
||||
@ -548,9 +533,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
if (biggest_attno < 0)
|
||||
break;
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Attempt to compress it inline
|
||||
* ----------
|
||||
*/
|
||||
i = biggest_attno;
|
||||
old_value = toast_values[i];
|
||||
@ -578,9 +562,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Finally we store attributes of type 'm' external
|
||||
* ----------
|
||||
*/
|
||||
while (MAXALIGN(ComputeDataSize(tupleDesc, toast_values, toast_nulls)) >
|
||||
maxDataLen && rel->rd_rel->reltoastrelid != InvalidOid)
|
||||
@ -589,10 +572,9 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
int32 biggest_size = MAXALIGN(sizeof(varattrib));
|
||||
Datum old_value;
|
||||
|
||||
/* ----------
|
||||
* Search for the biggest yet inlined attribute with
|
||||
* attstorage = 'm'
|
||||
* ----------
|
||||
/*
|
||||
* Search for the biggest yet inlined attribute with attstorage =
|
||||
* 'm'
|
||||
*/
|
||||
for (i = 0; i < numAttrs; i++)
|
||||
{
|
||||
@ -612,9 +594,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
if (biggest_attno < 0)
|
||||
break;
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Store this external
|
||||
* ----------
|
||||
*/
|
||||
i = biggest_attno;
|
||||
old_value = toast_values[i];
|
||||
@ -633,10 +614,9 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
need_free = true;
|
||||
}
|
||||
|
||||
/* ----------
|
||||
* In the case we toasted any values, we need to build
|
||||
* a new heap tuple with the changed values.
|
||||
* ----------
|
||||
/*
|
||||
* In the case we toasted any values, we need to build a new heap
|
||||
* tuple with the changed values.
|
||||
*/
|
||||
if (need_change)
|
||||
{
|
||||
@ -645,9 +625,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
MemoryContext oldcxt;
|
||||
HeapTupleHeader olddata;
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Calculate the new size of the tuple
|
||||
* ----------
|
||||
*/
|
||||
new_len = offsetof(HeapTupleHeaderData, t_bits);
|
||||
if (has_nulls)
|
||||
@ -655,19 +634,17 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
new_len = MAXALIGN(new_len);
|
||||
new_len += ComputeDataSize(tupleDesc, toast_values, toast_nulls);
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Remember the old memory location of the tuple (for below),
|
||||
* switch to the memory context of the HeapTuple structure
|
||||
* and allocate the new tuple.
|
||||
* ----------
|
||||
* switch to the memory context of the HeapTuple structure and
|
||||
* allocate the new tuple.
|
||||
*/
|
||||
olddata = newtup->t_data;
|
||||
oldcxt = MemoryContextSwitchTo(newtup->t_datamcxt);
|
||||
new_data = palloc(new_len);
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Put the tuple header and the changed values into place
|
||||
* ----------
|
||||
*/
|
||||
memcpy(new_data, newtup->t_data, newtup->t_data->t_hoff);
|
||||
newtup->t_data = (HeapTupleHeader) new_data;
|
||||
@ -682,33 +659,29 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
||||
&(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
|
||||
* ----------
|
||||
/*
|
||||
* In the case we modified a previously modified tuple again, free
|
||||
* the memory from the previous run
|
||||
*/
|
||||
if ((char *) olddata != ((char *) newtup + HEAPTUPLESIZE))
|
||||
pfree(olddata);
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Switch back to the old memory context
|
||||
* ----------
|
||||
*/
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
}
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Free allocated temp values
|
||||
* ----------
|
||||
*/
|
||||
if (need_free)
|
||||
for (i = 0; i < numAttrs; i++)
|
||||
if (toast_free[i])
|
||||
pfree(DatumGetPointer(toast_values[i]));
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Delete external values from the old tuple
|
||||
* ----------
|
||||
*/
|
||||
if (need_delold)
|
||||
for (i = 0; i < numAttrs; i++)
|
||||
@ -776,9 +749,8 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
|
||||
char *data_p;
|
||||
int32 data_todo;
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Create the varattrib reference
|
||||
* ----------
|
||||
*/
|
||||
result = (varattrib *) palloc(sizeof(varattrib));
|
||||
|
||||
@ -802,9 +774,8 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
|
||||
result->va_content.va_external.va_rowid = mainoid;
|
||||
result->va_content.va_external.va_attno = attno;
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Initialize constant parts of the tuple data
|
||||
* ----------
|
||||
*/
|
||||
t_values[0] = ObjectIdGetDatum(result->va_content.va_external.va_valueid);
|
||||
t_values[2] = PointerGetDatum(chunk_data);
|
||||
@ -812,36 +783,32 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
|
||||
t_nulls[1] = ' ';
|
||||
t_nulls[2] = ' ';
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Get the data to process
|
||||
* ----------
|
||||
*/
|
||||
data_p = VARATT_DATA(value);
|
||||
data_todo = VARATT_SIZE(value) - VARHDRSZ;
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Open the toast relation
|
||||
* ----------
|
||||
*/
|
||||
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
|
||||
* ----------
|
||||
*/
|
||||
while (data_todo > 0)
|
||||
{
|
||||
/* ----------
|
||||
|
||||
/*
|
||||
* Calculate the size of this chunk
|
||||
* ----------
|
||||
*/
|
||||
chunk_size = Min(TOAST_MAX_CHUNK_SIZE, data_todo);
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Build a tuple
|
||||
* ----------
|
||||
*/
|
||||
t_values[1] = Int32GetDatum(chunk_seq++);
|
||||
VARATT_SIZEP(chunk_data) = chunk_size + VARHDRSZ;
|
||||
@ -850,9 +817,8 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
|
||||
if (!HeapTupleIsValid(toasttup))
|
||||
elog(ERROR, "Failed to build TOAST tuple");
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Store it and create the index entry
|
||||
* ----------
|
||||
*/
|
||||
heap_insert(toastrel, toasttup);
|
||||
idxres = index_insert(toastidx, t_values, t_nulls,
|
||||
@ -861,24 +827,21 @@ toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
|
||||
if (idxres == NULL)
|
||||
elog(ERROR, "Failed to insert index entry for TOAST tuple");
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Free memory
|
||||
* ----------
|
||||
*/
|
||||
heap_freetuple(toasttup);
|
||||
pfree(idxres);
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Move on to next chunk
|
||||
* ----------
|
||||
*/
|
||||
data_todo -= chunk_size;
|
||||
data_p += chunk_size;
|
||||
}
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Done - close toast relation and return the reference
|
||||
* ----------
|
||||
*/
|
||||
index_close(toastidx);
|
||||
heap_close(toastrel, RowExclusiveLock);
|
||||
@ -908,17 +871,15 @@ toast_delete_datum(Relation rel, Datum value)
|
||||
if (!VARATT_IS_EXTERNAL(attr))
|
||||
return;
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Open the toast relation and it's index
|
||||
* ----------
|
||||
*/
|
||||
toastrel = heap_open(attr->va_content.va_external.va_toastrelid,
|
||||
RowExclusiveLock);
|
||||
toastidx = index_open(attr->va_content.va_external.va_toastidxid);
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Setup a scan key to fetch from the index by va_valueid
|
||||
* ----------
|
||||
*/
|
||||
ScanKeyEntryInitialize(&toastkey,
|
||||
(bits16) 0,
|
||||
@ -926,9 +887,8 @@ toast_delete_datum(Relation rel, Datum value)
|
||||
(RegProcedure) F_OIDEQ,
|
||||
ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Read the chunks by index
|
||||
* ----------
|
||||
*/
|
||||
toastscan = index_beginscan(toastidx, false, 1, &toastkey);
|
||||
while ((indexRes = index_getnext(toastscan, ForwardScanDirection)) != NULL)
|
||||
@ -940,18 +900,16 @@ toast_delete_datum(Relation rel, Datum value)
|
||||
if (!toasttup.t_data)
|
||||
continue;
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Have a chunk, delete it
|
||||
* ----------
|
||||
*/
|
||||
simple_heap_delete(toastrel, &toasttup.t_self);
|
||||
|
||||
ReleaseBuffer(buffer);
|
||||
}
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* End scan and close relations
|
||||
* ----------
|
||||
*/
|
||||
index_endscan(toastscan);
|
||||
index_close(toastidx);
|
||||
@ -1003,18 +961,16 @@ toast_fetch_datum(varattrib *attr)
|
||||
if (VARATT_IS_COMPRESSED(attr))
|
||||
VARATT_SIZEP(result) |= VARATT_FLAG_COMPRESSED;
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Open the toast relation and it's index
|
||||
* ----------
|
||||
*/
|
||||
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);
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Setup a scan key to fetch from the index by va_valueid
|
||||
* ----------
|
||||
*/
|
||||
ScanKeyEntryInitialize(&toastkey,
|
||||
(bits16) 0,
|
||||
@ -1022,11 +978,10 @@ toast_fetch_datum(varattrib *attr)
|
||||
(RegProcedure) F_OIDEQ,
|
||||
ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Read the chunks by index
|
||||
*
|
||||
* Note we will not necessarily see the chunks in sequence-number order.
|
||||
* ----------
|
||||
*/
|
||||
toastscan = index_beginscan(toastidx, false, 1, &toastkey);
|
||||
while ((indexRes = index_getnext(toastscan, ForwardScanDirection)) != NULL)
|
||||
@ -1039,9 +994,8 @@ toast_fetch_datum(varattrib *attr)
|
||||
continue;
|
||||
ttup = &toasttup;
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Have a chunk, extract the sequence number and the data
|
||||
* ----------
|
||||
*/
|
||||
residx = DatumGetInt32(heap_getattr(ttup, 2, toasttupDesc, &isnull));
|
||||
Assert(!isnull);
|
||||
@ -1049,9 +1003,8 @@ toast_fetch_datum(varattrib *attr)
|
||||
Assert(!isnull);
|
||||
chunksize = VARATT_SIZE(chunk) - VARHDRSZ;
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Some checks on the data we've found
|
||||
* ----------
|
||||
*/
|
||||
if (residx < 0 || residx >= numchunks)
|
||||
elog(ERROR, "unexpected chunk number %d for toast value %d",
|
||||
@ -1076,9 +1029,8 @@ toast_fetch_datum(varattrib *attr)
|
||||
residx,
|
||||
attr->va_content.va_external.va_valueid);
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Copy the data into proper place in our result
|
||||
* ----------
|
||||
*/
|
||||
memcpy(((char *) VARATT_DATA(result)) + residx * TOAST_MAX_CHUNK_SIZE,
|
||||
VARATT_DATA(chunk),
|
||||
@ -1087,9 +1039,8 @@ toast_fetch_datum(varattrib *attr)
|
||||
ReleaseBuffer(buffer);
|
||||
}
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* Final checks that we successfully fetched the datum
|
||||
* ----------
|
||||
*/
|
||||
if (memcmp(chunks_found, chunks_expected, numchunks) != 0)
|
||||
elog(ERROR, "not all toast chunks found for value %d",
|
||||
@ -1097,9 +1048,8 @@ toast_fetch_datum(varattrib *attr)
|
||||
pfree(chunks_expected);
|
||||
pfree(chunks_found);
|
||||
|
||||
/* ----------
|
||||
/*
|
||||
* End scan and close relations
|
||||
* ----------
|
||||
*/
|
||||
index_endscan(toastscan);
|
||||
index_close(toastidx);
|
||||
|
Reference in New Issue
Block a user