1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-08 06:02:22 +03:00

8.4 pgindent run, with new combined Linux/FreeBSD/MinGW typedef list

provided by Andrew.
This commit is contained in:
Bruce Momjian
2009-06-11 14:49:15 +00:00
parent 4e86efb4e5
commit d747140279
654 changed files with 11900 additions and 11387 deletions

View File

@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gin/ginget.c,v 1.26 2009/05/19 02:48:26 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/gin/ginget.c,v 1.27 2009/06/11 14:48:53 momjian Exp $
*-------------------------------------------------------------------------
*/
@@ -25,10 +25,10 @@
typedef struct pendingPosition
{
Buffer pendingBuffer;
OffsetNumber firstOffset;
OffsetNumber lastOffset;
ItemPointerData item;
Buffer pendingBuffer;
OffsetNumber firstOffset;
OffsetNumber lastOffset;
ItemPointerData item;
} pendingPosition;
@@ -64,19 +64,19 @@ findItemInPage(Page page, ItemPointer item, OffsetNumber *off)
* Goes to the next page if current offset is outside of bounds
*/
static bool
moveRightIfItNeeded( GinBtreeData *btree, GinBtreeStack *stack )
moveRightIfItNeeded(GinBtreeData *btree, GinBtreeStack *stack)
{
Page page = BufferGetPage(stack->buffer);
Page page = BufferGetPage(stack->buffer);
if ( stack->off > PageGetMaxOffsetNumber(page) )
if (stack->off > PageGetMaxOffsetNumber(page))
{
/*
* We scanned the whole page, so we should take right page
*/
stack->blkno = GinPageGetOpaque(page)->rightlink;
if ( GinPageRightMost(page) )
return false; /* no more pages */
if (GinPageRightMost(page))
return false; /* no more pages */
LockBuffer(stack->buffer, GIN_UNLOCK);
stack->buffer = ReleaseAndReadBuffer(stack->buffer, btree->index, stack->blkno);
@@ -92,12 +92,12 @@ moveRightIfItNeeded( GinBtreeData *btree, GinBtreeStack *stack )
* in scanEntry->partialMatch TIDBitmap
*/
static void
scanForItems( Relation index, GinScanEntry scanEntry, BlockNumber rootPostingTree )
scanForItems(Relation index, GinScanEntry scanEntry, BlockNumber rootPostingTree)
{
GinPostingTreeScan *gdi;
Buffer buffer;
Page page;
BlockNumber blkno;
Buffer buffer;
Page page;
BlockNumber blkno;
gdi = prepareScanPostingTree(index, rootPostingTree, TRUE);
@@ -110,23 +110,23 @@ scanForItems( Relation index, GinScanEntry scanEntry, BlockNumber rootPostingTre
/*
* Goes through all leaves
*/
for(;;)
for (;;)
{
page = BufferGetPage(buffer);
if ((GinPageGetOpaque(page)->flags & GIN_DELETED) == 0 && GinPageGetOpaque(page)->maxoff >= FirstOffsetNumber )
if ((GinPageGetOpaque(page)->flags & GIN_DELETED) == 0 && GinPageGetOpaque(page)->maxoff >= FirstOffsetNumber)
{
tbm_add_tuples( scanEntry->partialMatch,
(ItemPointer)GinDataPageGetItem(page, FirstOffsetNumber),
GinPageGetOpaque(page)->maxoff, false);
tbm_add_tuples(scanEntry->partialMatch,
(ItemPointer) GinDataPageGetItem(page, FirstOffsetNumber),
GinPageGetOpaque(page)->maxoff, false);
scanEntry->predictNumberResult += GinPageGetOpaque(page)->maxoff;
}
blkno = GinPageGetOpaque(page)->rightlink;
if ( GinPageRightMost(page) )
if (GinPageRightMost(page))
{
UnlockReleaseBuffer(buffer);
return; /* no more pages */
return; /* no more pages */
}
LockBuffer(buffer, GIN_UNLOCK);
@@ -142,21 +142,21 @@ scanForItems( Relation index, GinScanEntry scanEntry, BlockNumber rootPostingTre
* Returns true if done, false if it's needed to restart scan from scratch
*/
static bool
computePartialMatchList( GinBtreeData *btree, GinBtreeStack *stack, GinScanEntry scanEntry )
computePartialMatchList(GinBtreeData *btree, GinBtreeStack *stack, GinScanEntry scanEntry)
{
Page page;
IndexTuple itup;
Page page;
IndexTuple itup;
Datum idatum;
int32 cmp;
scanEntry->partialMatch = tbm_create( work_mem * 1024L );
scanEntry->partialMatch = tbm_create(work_mem * 1024L);
for(;;)
for (;;)
{
/*
* stack->off points to the interested entry, buffer is already locked
*/
if ( moveRightIfItNeeded(btree, stack) == false )
if (moveRightIfItNeeded(btree, stack) == false)
return true;
page = BufferGetPage(stack->buffer);
@@ -165,10 +165,10 @@ computePartialMatchList( GinBtreeData *btree, GinBtreeStack *stack, GinScanEntry
/*
* If tuple stores another attribute then stop scan
*/
if ( gintuple_get_attrnum( btree->ginstate, itup ) != scanEntry->attnum )
if (gintuple_get_attrnum(btree->ginstate, itup) != scanEntry->attnum)
return true;
idatum = gin_index_getattr( btree->ginstate, itup );
idatum = gin_index_getattr(btree->ginstate, itup);
/*----------
@@ -178,74 +178,74 @@ computePartialMatchList( GinBtreeData *btree, GinBtreeStack *stack, GinScanEntry
* case cmp < 0 => not match and continue scan
*----------
*/
cmp = DatumGetInt32(FunctionCall4(&btree->ginstate->comparePartialFn[scanEntry->attnum-1],
cmp = DatumGetInt32(FunctionCall4(&btree->ginstate->comparePartialFn[scanEntry->attnum - 1],
scanEntry->entry,
idatum,
UInt16GetDatum(scanEntry->strategy),
PointerGetDatum(scanEntry->extra_data)));
PointerGetDatum(scanEntry->extra_data)));
if ( cmp > 0 )
if (cmp > 0)
return true;
else if ( cmp < 0 )
else if (cmp < 0)
{
stack->off++;
continue;
}
if ( GinIsPostingTree(itup) )
if (GinIsPostingTree(itup))
{
BlockNumber rootPostingTree = GinGetPostingTree(itup);
Datum newDatum,
savedDatum = datumCopy (
idatum,
btree->ginstate->origTupdesc->attrs[scanEntry->attnum-1]->attbyval,
btree->ginstate->origTupdesc->attrs[scanEntry->attnum-1]->attlen
);
savedDatum = datumCopy(
idatum,
btree->ginstate->origTupdesc->attrs[scanEntry->attnum - 1]->attbyval,
btree->ginstate->origTupdesc->attrs[scanEntry->attnum - 1]->attlen
);
/*
* We should unlock current page (but not unpin) during
* tree scan to prevent deadlock with vacuum processes.
* We should unlock current page (but not unpin) during tree scan
* to prevent deadlock with vacuum processes.
*
* We save current entry value (savedDatum) to be able to refind
* our tuple after re-locking
*/
LockBuffer(stack->buffer, GIN_UNLOCK);
scanForItems( btree->index, scanEntry, rootPostingTree );
scanForItems(btree->index, scanEntry, rootPostingTree);
/*
* We lock again the entry page and while it was unlocked
* insert might occured, so we need to refind our position
* We lock again the entry page and while it was unlocked insert
* might occured, so we need to refind our position
*/
LockBuffer(stack->buffer, GIN_SHARE);
page = BufferGetPage(stack->buffer);
if ( !GinPageIsLeaf(page) )
if (!GinPageIsLeaf(page))
{
/*
* Root page becomes non-leaf while we unlock it. We
* will start again, this situation doesn't cause
* often - root can became a non-leaf only one per
* life of index.
* Root page becomes non-leaf while we unlock it. We will
* start again, this situation doesn't cause often - root can
* became a non-leaf only one per life of index.
*/
return false;
}
for(;;)
for (;;)
{
if ( moveRightIfItNeeded(btree, stack) == false )
elog(ERROR, "lost saved point in index"); /* must not happen !!! */
if (moveRightIfItNeeded(btree, stack) == false)
elog(ERROR, "lost saved point in index"); /* must not happen !!! */
page = BufferGetPage(stack->buffer);
itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, stack->off));
newDatum = gin_index_getattr( btree->ginstate, itup );
newDatum = gin_index_getattr(btree->ginstate, itup);
if ( gintuple_get_attrnum( btree->ginstate, itup ) != scanEntry->attnum )
elog(ERROR, "lost saved point in index"); /* must not happen !!! */
if (gintuple_get_attrnum(btree->ginstate, itup) != scanEntry->attnum)
elog(ERROR, "lost saved point in index"); /* must not happen !!! */
if ( compareEntries(btree->ginstate, scanEntry->attnum, newDatum, savedDatum) == 0 )
if (compareEntries(btree->ginstate, scanEntry->attnum, newDatum, savedDatum) == 0)
{
/* Found! */
if ( btree->ginstate->origTupdesc->attrs[scanEntry->attnum-1]->attbyval == false )
pfree( DatumGetPointer(savedDatum) );
if (btree->ginstate->origTupdesc->attrs[scanEntry->attnum - 1]->attbyval == false)
pfree(DatumGetPointer(savedDatum));
break;
}
@@ -254,8 +254,8 @@ computePartialMatchList( GinBtreeData *btree, GinBtreeStack *stack, GinScanEntry
}
else
{
tbm_add_tuples( scanEntry->partialMatch, GinGetPosting(itup), GinGetNPosting(itup), false);
scanEntry->predictNumberResult += GinGetNPosting(itup);
tbm_add_tuples(scanEntry->partialMatch, GinGetPosting(itup), GinGetNPosting(itup), false);
scanEntry->predictNumberResult += GinGetNPosting(itup);
}
/*
@@ -273,10 +273,10 @@ computePartialMatchList( GinBtreeData *btree, GinBtreeStack *stack, GinScanEntry
static void
startScanEntry(Relation index, GinState *ginstate, GinScanEntry entry)
{
GinBtreeData btreeEntry;
GinBtreeStack *stackEntry;
Page page;
bool needUnlock = TRUE;
GinBtreeData btreeEntry;
GinBtreeStack *stackEntry;
Page page;
bool needUnlock = TRUE;
entry->buffer = InvalidBuffer;
entry->offset = InvalidOffsetNumber;
@@ -294,8 +294,8 @@ startScanEntry(Relation index, GinState *ginstate, GinScanEntry entry)
}
/*
* we should find entry, and begin scan of posting tree
* or just store posting list in memory
* we should find entry, and begin scan of posting tree or just store
* posting list in memory
*/
prepareEntryScan(&btreeEntry, index, entry->attnum, entry->entry, ginstate);
@@ -305,27 +305,26 @@ startScanEntry(Relation index, GinState *ginstate, GinScanEntry entry)
entry->isFinished = TRUE;
if ( entry->isPartialMatch )
if (entry->isPartialMatch)
{
/*
* btreeEntry.findItem points to the first equal or greater value
* than needed. So we will scan further and collect all
* ItemPointers
* btreeEntry.findItem points to the first equal or greater value than
* needed. So we will scan further and collect all ItemPointers
*/
btreeEntry.findItem(&btreeEntry, stackEntry);
if ( computePartialMatchList( &btreeEntry, stackEntry, entry ) == false )
if (computePartialMatchList(&btreeEntry, stackEntry, entry) == false)
{
/*
* GIN tree was seriously restructured, so we will
* cleanup all found data and rescan. See comments near
* 'return false' in computePartialMatchList()
* GIN tree was seriously restructured, so we will cleanup all
* found data and rescan. See comments near 'return false' in
* computePartialMatchList()
*/
if ( entry->partialMatch )
if (entry->partialMatch)
{
if (entry->partialMatchIterator)
tbm_end_iterate(entry->partialMatchIterator);
entry->partialMatchIterator = NULL;
tbm_free( entry->partialMatch );
tbm_free(entry->partialMatch);
entry->partialMatch = NULL;
}
LockBuffer(stackEntry->buffer, GIN_UNLOCK);
@@ -335,7 +334,7 @@ startScanEntry(Relation index, GinState *ginstate, GinScanEntry entry)
return;
}
if ( entry->partialMatch && !tbm_is_empty(entry->partialMatch) )
if (entry->partialMatch && !tbm_is_empty(entry->partialMatch))
{
entry->partialMatchIterator = tbm_begin_iterate(entry->partialMatch);
entry->isFinished = FALSE;
@@ -352,22 +351,22 @@ startScanEntry(Relation index, GinState *ginstate, GinScanEntry entry)
Page page;
/*
* We should unlock entry page before make deal with
* posting tree to prevent deadlocks with vacuum processes.
* Because entry is never deleted from page and posting tree is
* never reduced to the posting list, we can unlock page after
* getting BlockNumber of root of posting tree.
* We should unlock entry page before make deal with posting tree
* to prevent deadlocks with vacuum processes. Because entry is
* never deleted from page and posting tree is never reduced to
* the posting list, we can unlock page after getting BlockNumber
* of root of posting tree.
*/
LockBuffer(stackEntry->buffer, GIN_UNLOCK);
needUnlock = FALSE;
gdi = prepareScanPostingTree(index, rootPostingTree, TRUE);
entry->buffer = scanBeginPostingTree(gdi);
/*
* We keep buffer pinned because we need to prevent deletion of
* page during scan. See GIN's vacuum implementation. RefCount
* is increased to keep buffer pinned after freeGinBtreeStack()
* call.
* page during scan. See GIN's vacuum implementation. RefCount is
* increased to keep buffer pinned after freeGinBtreeStack() call.
*/
IncrBufferRefCount(entry->buffer);
@@ -377,10 +376,10 @@ startScanEntry(Relation index, GinState *ginstate, GinScanEntry entry)
/*
* Keep page content in memory to prevent durable page locking
*/
entry->list = (ItemPointerData *) palloc( BLCKSZ );
entry->list = (ItemPointerData *) palloc(BLCKSZ);
entry->nlist = GinPageGetOpaque(page)->maxoff;
memcpy( entry->list, GinDataPageGetItem(page, FirstOffsetNumber),
GinPageGetOpaque(page)->maxoff * sizeof(ItemPointerData) );
memcpy(entry->list, GinDataPageGetItem(page, FirstOffsetNumber),
GinPageGetOpaque(page)->maxoff * sizeof(ItemPointerData));
LockBuffer(entry->buffer, GIN_UNLOCK);
freeGinBtreeStack(gdi->stack);
@@ -397,7 +396,7 @@ startScanEntry(Relation index, GinState *ginstate, GinScanEntry entry)
}
if (needUnlock)
LockBuffer(stackEntry->buffer, GIN_UNLOCK);
LockBuffer(stackEntry->buffer, GIN_UNLOCK);
freeGinBtreeStack(stackEntry);
}
@@ -419,10 +418,10 @@ startScanKey(Relation index, GinState *ginstate, GinScanKey key)
if (GinFuzzySearchLimit > 0)
{
/*
* If all of keys more than threshold we will try to reduce
* result, we hope (and only hope, for intersection operation of
* array our supposition isn't true), that total result will not
* more than minimal predictNumberResult.
* If all of keys more than threshold we will try to reduce result, we
* hope (and only hope, for intersection operation of array our
* supposition isn't true), that total result will not more than
* minimal predictNumberResult.
*/
for (i = 0; i < key->nentries; i++)
@@ -459,7 +458,7 @@ entryGetNextItem(Relation index, GinScanEntry entry)
Page page;
BlockNumber blkno;
for(;;)
for (;;)
{
entry->offset++;
@@ -471,7 +470,7 @@ entryGetNextItem(Relation index, GinScanEntry entry)
LockBuffer(entry->buffer, GIN_SHARE);
page = BufferGetPage(entry->buffer);
for(;;)
for (;;)
{
/*
* It's needed to go by right link. During that we should refind
@@ -501,20 +500,20 @@ entryGetNextItem(Relation index, GinScanEntry entry)
* Found position equal to or greater than stored
*/
entry->nlist = GinPageGetOpaque(page)->maxoff;
memcpy( entry->list, GinDataPageGetItem(page, FirstOffsetNumber),
GinPageGetOpaque(page)->maxoff * sizeof(ItemPointerData) );
memcpy(entry->list, GinDataPageGetItem(page, FirstOffsetNumber),
GinPageGetOpaque(page)->maxoff * sizeof(ItemPointerData));
LockBuffer(entry->buffer, GIN_UNLOCK);
if ( !ItemPointerIsValid(&entry->curItem) ||
compareItemPointers( &entry->curItem, entry->list + entry->offset - 1 ) == 0 )
if (!ItemPointerIsValid(&entry->curItem) ||
compareItemPointers(&entry->curItem, entry->list + entry->offset - 1) == 0)
{
/*
* First pages are deleted or empty, or we found exact position,
* so break inner loop and continue outer one.
* First pages are deleted or empty, or we found exact
* position, so break inner loop and continue outer one.
*/
break;
break;
}
/*
@@ -543,7 +542,7 @@ entryGetItem(Relation index, GinScanEntry entry)
entry->isFinished = entry->master->isFinished;
entry->curItem = entry->master->curItem;
}
else if ( entry->partialMatch )
else if (entry->partialMatch)
{
do
{
@@ -552,7 +551,7 @@ entryGetItem(Relation index, GinScanEntry entry)
{
entry->partialMatchResult = tbm_iterate(entry->partialMatchIterator);
if ( entry->partialMatchResult == NULL )
if (entry->partialMatchResult == NULL)
{
ItemPointerSet(&entry->curItem, InvalidBlockNumber, InvalidOffsetNumber);
tbm_end_iterate(entry->partialMatchIterator);
@@ -562,22 +561,23 @@ entryGetItem(Relation index, GinScanEntry entry)
}
/*
* reset counter to the beginning of entry->partialMatchResult.
* Note: entry->offset is still greater than
* partialMatchResult->ntuples if partialMatchResult is
* lossy. So, on next call we will get next result from
* TIDBitmap.
* reset counter to the beginning of
* entry->partialMatchResult. Note: entry->offset is still
* greater than partialMatchResult->ntuples if
* partialMatchResult is lossy. So, on next call we will get
* next result from TIDBitmap.
*/
entry->offset = 0;
}
if ( entry->partialMatchResult->ntuples < 0 )
if (entry->partialMatchResult->ntuples < 0)
{
/*
* lossy result, so we need to check the whole page
*/
ItemPointerSetLossyPage(&entry->curItem,
entry->partialMatchResult->blockno);
/*
* We might as well fall out of the loop; we could not
* estimate number of results on this page to support correct
@@ -618,7 +618,7 @@ entryGetItem(Relation index, GinScanEntry entry)
* Sets key->curItem to new found heap item pointer for one scan key
* Returns isFinished, ie TRUE means we did NOT get a new item pointer!
* Also, *keyrecheck is set true if recheck is needed for this scan key.
* Note: lossy page could be returned after items from the same page.
* Note: lossy page could be returned after items from the same page.
*/
static bool
keyGetItem(Relation index, GinState *ginstate, MemoryContext tempCtx,
@@ -636,10 +636,10 @@ keyGetItem(Relation index, GinState *ginstate, MemoryContext tempCtx,
{
/*
* move forward from previously value and set new curItem, which is
* minimal from entries->curItems. Lossy page is encoded by ItemPointer
* with max value for offset (0xffff), so if there is an non-lossy entries
* on lossy page they will returned too and after that the whole page.
* That's not a problem for resulting tidbitmap.
* minimal from entries->curItems. Lossy page is encoded by
* ItemPointer with max value for offset (0xffff), so if there is an
* non-lossy entries on lossy page they will returned too and after
* that the whole page. That's not a problem for resulting tidbitmap.
*/
ItemPointerSetMax(&key->curItem);
for (i = 0; i < key->nentries; i++)
@@ -649,9 +649,9 @@ keyGetItem(Relation index, GinState *ginstate, MemoryContext tempCtx,
if (key->entryRes[i])
{
/*
* Move forward only entries which was the least
* on previous call, key->entryRes[i] points that
* current entry was a result of loop/call.
* Move forward only entries which was the least on previous
* call, key->entryRes[i] points that current entry was a
* result of loop/call.
*/
if (entry->isFinished == FALSE && entryGetItem(index, entry) == FALSE)
{
@@ -685,10 +685,10 @@ keyGetItem(Relation index, GinState *ginstate, MemoryContext tempCtx,
/*----------
* entryRes array is used for:
* - as an argument for consistentFn
* - entry->curItem with corresponding key->entryRes[i] == false are
* greater than key->curItem, so next loop/call they should be
* renewed by entryGetItem(). So, we need to set up an array before
* checking of lossy page.
* - entry->curItem with corresponding key->entryRes[i] == false are
* greater than key->curItem, so next loop/call they should be
* renewed by entryGetItem(). So, we need to set up an array before
* checking of lossy page.
*----------
*/
for (i = 0; i < key->nentries; i++)
@@ -717,7 +717,7 @@ keyGetItem(Relation index, GinState *ginstate, MemoryContext tempCtx,
return FALSE;
oldCtx = MemoryContextSwitchTo(tempCtx);
res = DatumGetBool(FunctionCall6(&ginstate->consistentFn[key->attnum-1],
res = DatumGetBool(FunctionCall6(&ginstate->consistentFn[key->attnum - 1],
PointerGetDatum(key->entryRes),
UInt16GetDatum(key->strategy),
key->query,
@@ -745,35 +745,36 @@ keyGetItem(Relation index, GinState *ginstate, MemoryContext tempCtx,
static bool
scanGetCandidate(IndexScanDesc scan, pendingPosition *pos)
{
OffsetNumber maxoff;
Page page;
IndexTuple itup;
OffsetNumber maxoff;
Page page;
IndexTuple itup;
ItemPointerSetInvalid( &pos->item );
for(;;)
ItemPointerSetInvalid(&pos->item);
for (;;)
{
page = BufferGetPage(pos->pendingBuffer);
maxoff = PageGetMaxOffsetNumber(page);
if ( pos->firstOffset > maxoff )
if (pos->firstOffset > maxoff)
{
BlockNumber blkno = GinPageGetOpaque(page)->rightlink;
if ( blkno == InvalidBlockNumber )
if (blkno == InvalidBlockNumber)
{
UnlockReleaseBuffer(pos->pendingBuffer);
pos->pendingBuffer=InvalidBuffer;
pos->pendingBuffer = InvalidBuffer;
return false;
}
else
{
/*
* Here we must prevent deletion of next page by
* insertcleanup process, which may be trying to obtain
* exclusive lock on current page. So, we lock next
* page before releasing the current one
* Here we must prevent deletion of next page by insertcleanup
* process, which may be trying to obtain exclusive lock on
* current page. So, we lock next page before releasing the
* current one
*/
Buffer tmpbuf = ReadBuffer(scan->indexRelation, blkno);
Buffer tmpbuf = ReadBuffer(scan->indexRelation, blkno);
LockBuffer(tmpbuf, GIN_SHARE);
UnlockReleaseBuffer(pos->pendingBuffer);
@@ -786,12 +787,12 @@ scanGetCandidate(IndexScanDesc scan, pendingPosition *pos)
{
itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, pos->firstOffset));
pos->item = itup->t_tid;
if ( GinPageHasFullRow(page) )
if (GinPageHasFullRow(page))
{
/*
* find itempointer to the next row
*/
for(pos->lastOffset = pos->firstOffset+1; pos->lastOffset<=maxoff; pos->lastOffset++)
for (pos->lastOffset = pos->firstOffset + 1; pos->lastOffset <= maxoff; pos->lastOffset++)
{
itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, pos->lastOffset));
if (!ItemPointerEquals(&pos->item, &itup->t_tid))
@@ -807,9 +808,9 @@ scanGetCandidate(IndexScanDesc scan, pendingPosition *pos)
}
/*
* Now pos->firstOffset points to the first tuple of current heap row,
* pos->lastOffset points to the first tuple of second heap row (or
* to the end of page)
* Now pos->firstOffset points to the first tuple of current heap
* row, pos->lastOffset points to the first tuple of second heap
* row (or to the end of page)
*/
break;
@@ -830,23 +831,23 @@ static bool
matchPartialInPendingList(GinState *ginstate, Page page,
OffsetNumber off, OffsetNumber maxoff,
Datum value, OffsetNumber attrnum,
Datum *datum, bool *datumExtracted,
Datum *datum, bool *datumExtracted,
StrategyNumber strategy,
Pointer extra_data)
{
IndexTuple itup;
int32 cmp;
IndexTuple itup;
int32 cmp;
while ( off < maxoff )
while (off < maxoff)
{
itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, off));
if ( attrnum != gintuple_get_attrnum(ginstate, itup) )
if (attrnum != gintuple_get_attrnum(ginstate, itup))
return false;
if (datumExtracted[ off-1 ] == false)
if (datumExtracted[off - 1] == false)
{
datum[ off-1 ] = gin_index_getattr(ginstate, itup);
datumExtracted[ off-1 ] = true;
datum[off - 1] = gin_index_getattr(ginstate, itup);
datumExtracted[off - 1] = true;
}
/*----------
@@ -856,9 +857,9 @@ matchPartialInPendingList(GinState *ginstate, Page page,
* case cmp < 0 => not match and continue scan
*----------
*/
cmp = DatumGetInt32(FunctionCall4(&ginstate->comparePartialFn[attrnum-1],
cmp = DatumGetInt32(FunctionCall4(&ginstate->comparePartialFn[attrnum - 1],
value,
datum[off-1],
datum[off - 1],
UInt16GetDatum(strategy),
PointerGetDatum(extra_data)));
if (cmp == 0)
@@ -882,12 +883,13 @@ matchPartialInPendingList(GinState *ginstate, Page page,
static bool
collectDatumForItem(IndexScanDesc scan, pendingPosition *pos)
{
GinScanOpaque so = (GinScanOpaque) scan->opaque;
OffsetNumber attrnum;
Page page;
IndexTuple itup;
int i, j;
bool hasMatch = false;
GinScanOpaque so = (GinScanOpaque) scan->opaque;
OffsetNumber attrnum;
Page page;
IndexTuple itup;
int i,
j;
bool hasMatch = false;
/*
* Resets entryRes
@@ -895,38 +897,40 @@ collectDatumForItem(IndexScanDesc scan, pendingPosition *pos)
for (i = 0; i < so->nkeys; i++)
{
GinScanKey key = so->keys + i;
memset( key->entryRes, FALSE, key->nentries );
memset(key->entryRes, FALSE, key->nentries);
}
for(;;)
for (;;)
{
Datum datum[ BLCKSZ/sizeof(IndexTupleData) ];
bool datumExtracted[ BLCKSZ/sizeof(IndexTupleData) ];
Datum datum[BLCKSZ / sizeof(IndexTupleData)];
bool datumExtracted[BLCKSZ / sizeof(IndexTupleData)];
Assert( pos->lastOffset > pos->firstOffset );
memset(datumExtracted + pos->firstOffset - 1, 0, sizeof(bool) * (pos->lastOffset - pos->firstOffset ));
Assert(pos->lastOffset > pos->firstOffset);
memset(datumExtracted + pos->firstOffset - 1, 0, sizeof(bool) * (pos->lastOffset - pos->firstOffset));
page = BufferGetPage(pos->pendingBuffer);
for(i = 0; i < so->nkeys; i++)
for (i = 0; i < so->nkeys; i++)
{
GinScanKey key = so->keys + i;
GinScanKey key = so->keys + i;
for(j=0; j<key->nentries; j++)
for (j = 0; j < key->nentries; j++)
{
OffsetNumber StopLow = pos->firstOffset,
StopHigh = pos->lastOffset,
StopMiddle;
GinScanEntry entry = key->scanEntry + j;
OffsetNumber StopLow = pos->firstOffset,
StopHigh = pos->lastOffset,
StopMiddle;
GinScanEntry entry = key->scanEntry + j;
/* already true - do not extra work */
if ( key->entryRes[j] )
if (key->entryRes[j])
continue;
/*
* Interested tuples are from pos->firstOffset to pos->lastOffset
* and they are ordered by (attnum, Datum) as it's done in entry tree
* So we could use binary search to prevent linear scanning
* Interested tuples are from pos->firstOffset to
* pos->lastOffset and they are ordered by (attnum, Datum) as
* it's done in entry tree So we could use binary search to
* prevent linear scanning
*/
while (StopLow < StopHigh)
{
@@ -941,53 +945,53 @@ collectDatumForItem(IndexScanDesc scan, pendingPosition *pos)
StopLow = StopMiddle + 1;
else
{
int res;
int res;
if (datumExtracted[ StopMiddle-1 ] == false)
if (datumExtracted[StopMiddle - 1] == false)
{
datum[ StopMiddle-1 ] = gin_index_getattr(&so->ginstate, itup);
datumExtracted[ StopMiddle-1 ] = true;
datum[StopMiddle - 1] = gin_index_getattr(&so->ginstate, itup);
datumExtracted[StopMiddle - 1] = true;
}
res = compareEntries(&so->ginstate,
entry->attnum,
entry->entry,
datum[ StopMiddle-1 ]);
res = compareEntries(&so->ginstate,
entry->attnum,
entry->entry,
datum[StopMiddle - 1]);
if ( res == 0 )
if (res == 0)
{
/*
* The exact match causes, so we just scan from
* current position to find a partial match.
* See comment above about tuple's ordering.
* The exact match causes, so we just scan from
* current position to find a partial match. See
* comment above about tuple's ordering.
*/
if ( entry->isPartialMatch )
if (entry->isPartialMatch)
key->entryRes[j] =
matchPartialInPendingList(&so->ginstate,
page, StopMiddle,
page, StopMiddle,
pos->lastOffset,
entry->entry,
entry->attnum,
datum,
datumExtracted,
entry->strategy,
entry->extra_data);
entry->extra_data);
else
key->entryRes[j] = true;
break;
}
else if ( res < 0 )
else if (res < 0)
StopHigh = StopMiddle;
else
StopLow = StopMiddle + 1;
}
}
if ( StopLow>=StopHigh && entry->isPartialMatch )
if (StopLow >= StopHigh && entry->isPartialMatch)
{
/*
* The exact match wasn't found, so we need to start
* scan from first tuple greater then current entry
* See comment above about tuple's ordering.
/*
* The exact match wasn't found, so we need to start scan
* from first tuple greater then current entry See comment
* above about tuple's ordering.
*/
key->entryRes[j] =
matchPartialInPendingList(&so->ginstate,
@@ -1007,7 +1011,7 @@ collectDatumForItem(IndexScanDesc scan, pendingPosition *pos)
pos->firstOffset = pos->lastOffset;
if ( GinPageHasFullRow(page) )
if (GinPageHasFullRow(page))
{
/*
* We scan all values from one tuple, go to next one
@@ -1020,12 +1024,13 @@ collectDatumForItem(IndexScanDesc scan, pendingPosition *pos)
ItemPointerData item = pos->item;
/*
* need to get next portion of tuples of row containing
* on several pages
* need to get next portion of tuples of row containing on several
* pages
*/
if ( scanGetCandidate(scan, pos) == false || !ItemPointerEquals(&pos->item, &item) )
elog(ERROR,"Could not process tuple"); /* XXX should not be here ! */
if (scanGetCandidate(scan, pos) == false || !ItemPointerEquals(&pos->item, &item))
elog(ERROR, "Could not process tuple"); /* XXX should not be
* here ! */
}
}
@@ -1039,12 +1044,14 @@ static void
scanPendingInsert(IndexScanDesc scan, TIDBitmap *tbm, int64 *ntids)
{
GinScanOpaque so = (GinScanOpaque) scan->opaque;
MemoryContext oldCtx;
bool recheck, keyrecheck, match;
int i;
pendingPosition pos;
Buffer metabuffer = ReadBuffer(scan->indexRelation, GIN_METAPAGE_BLKNO);
BlockNumber blkno;
MemoryContext oldCtx;
bool recheck,
keyrecheck,
match;
int i;
pendingPosition pos;
Buffer metabuffer = ReadBuffer(scan->indexRelation, GIN_METAPAGE_BLKNO);
BlockNumber blkno;
*ntids = 0;
@@ -1052,39 +1059,38 @@ scanPendingInsert(IndexScanDesc scan, TIDBitmap *tbm, int64 *ntids)
blkno = GinPageGetMeta(BufferGetPage(metabuffer))->head;
/*
* fetch head of list before unlocking metapage.
* head page must be pinned to prevent deletion by vacuum process
* fetch head of list before unlocking metapage. head page must be pinned
* to prevent deletion by vacuum process
*/
if ( blkno == InvalidBlockNumber )
if (blkno == InvalidBlockNumber)
{
/* No pending list, so proceed with normal scan */
UnlockReleaseBuffer( metabuffer );
UnlockReleaseBuffer(metabuffer);
return;
}
pos.pendingBuffer = ReadBuffer(scan->indexRelation, blkno);
LockBuffer(pos.pendingBuffer, GIN_SHARE);
pos.firstOffset = FirstOffsetNumber;
UnlockReleaseBuffer( metabuffer );
UnlockReleaseBuffer(metabuffer);
/*
* loop for each heap row. scanGetCandidate returns full row
* or row's tuples from first page.
* loop for each heap row. scanGetCandidate returns full row or row's
* tuples from first page.
*/
while( scanGetCandidate(scan, &pos) )
while (scanGetCandidate(scan, &pos))
{
/*
* Check entries in tuple and setup entryRes array
* If tuples of heap's row are placed on several pages
* collectDatumForItem will read all of that pages.
* Check entries in tuple and setup entryRes array If tuples of heap's
* row are placed on several pages collectDatumForItem will read all
* of that pages.
*/
if (!collectDatumForItem(scan, &pos))
continue;
/*
* Matching of entries of one row is finished,
* so check row by consistent function.
* Matching of entries of one row is finished, so check row by
* consistent function.
*/
oldCtx = MemoryContextSwitchTo(so->tempCtx);
recheck = false;
@@ -1092,11 +1098,11 @@ scanPendingInsert(IndexScanDesc scan, TIDBitmap *tbm, int64 *ntids)
for (i = 0; i < so->nkeys; i++)
{
GinScanKey key = so->keys + i;
GinScanKey key = so->keys + i;
keyrecheck = true;
if (!DatumGetBool(FunctionCall6(&so->ginstate.consistentFn[key->attnum-1],
if (!DatumGetBool(FunctionCall6(&so->ginstate.consistentFn[key->attnum - 1],
PointerGetDatum(key->entryRes),
UInt16GetDatum(key->strategy),
key->query,
@@ -1114,7 +1120,7 @@ scanPendingInsert(IndexScanDesc scan, TIDBitmap *tbm, int64 *ntids)
MemoryContextSwitchTo(oldCtx);
MemoryContextReset(so->tempCtx);
if ( match )
if (match)
{
tbm_add_tuples(tbm, &pos.item, 1, recheck);
(*ntids)++;
@@ -1137,10 +1143,10 @@ scanGetItem(IndexScanDesc scan, ItemPointerData *item, bool *recheck)
* We return recheck = true if any of the keyGetItem calls return
* keyrecheck = true. Note that because the second loop might advance
* some keys, this could theoretically be too conservative. In practice
* though, we expect that a consistentFn's recheck result will depend
* only on the operator and the query, so for any one key it should
* stay the same regardless of advancing to new items. So it's not
* worth working harder.
* though, we expect that a consistentFn's recheck result will depend only
* on the operator and the query, so for any one key it should stay the
* same regardless of advancing to new items. So it's not worth working
* harder.
*/
*recheck = false;
@@ -1165,13 +1171,13 @@ scanGetItem(IndexScanDesc scan, ItemPointerData *item, bool *recheck)
{
int cmp = compareItemPointers(item, &key->curItem);
if ( cmp != 0 && (ItemPointerIsLossyPage(item) || ItemPointerIsLossyPage(&key->curItem)) )
if (cmp != 0 && (ItemPointerIsLossyPage(item) || ItemPointerIsLossyPage(&key->curItem)))
{
/*
* if one of ItemPointers points to the whole page then
* compare only page's number
*/
if ( ItemPointerGetBlockNumber(item) == ItemPointerGetBlockNumber(&key->curItem) )
if (ItemPointerGetBlockNumber(item) == ItemPointerGetBlockNumber(&key->curItem))
cmp = 0;
else
cmp = (ItemPointerGetBlockNumber(item) > ItemPointerGetBlockNumber(&key->curItem)) ? 1 : -1;
@@ -1205,7 +1211,7 @@ Datum
gingetbitmap(PG_FUNCTION_ARGS)
{
IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
TIDBitmap *tbm = (TIDBitmap *) PG_GETARG_POINTER(1);
TIDBitmap *tbm = (TIDBitmap *) PG_GETARG_POINTER(1);
int64 ntids;
if (GinIsNewKey(scan))
@@ -1217,15 +1223,14 @@ gingetbitmap(PG_FUNCTION_ARGS)
ntids = 0;
/*
* First, scan the pending list and collect any matching entries into
* the bitmap. After we scan a pending item, some other backend could
* post it into the main index, and so we might visit it a second time
* during the main scan. This is okay because we'll just re-set the
* same bit in the bitmap. (The possibility of duplicate visits is a
* major reason why GIN can't support the amgettuple API, however.)
* Note that it would not do to scan the main index before the pending
* list, since concurrent cleanup could then make us miss entries
* entirely.
* First, scan the pending list and collect any matching entries into the
* bitmap. After we scan a pending item, some other backend could post it
* into the main index, and so we might visit it a second time during the
* main scan. This is okay because we'll just re-set the same bit in the
* bitmap. (The possibility of duplicate visits is a major reason why GIN
* can't support the amgettuple API, however.) Note that it would not do
* to scan the main index before the pending list, since concurrent
* cleanup could then make us miss entries entirely.
*/
scanPendingInsert(scan, tbm, &ntids);
@@ -1244,7 +1249,7 @@ gingetbitmap(PG_FUNCTION_ARGS)
if (!scanGetItem(scan, &iptr, &recheck))
break;
if ( ItemPointerIsLossyPage(&iptr) )
if (ItemPointerIsLossyPage(&iptr))
tbm_add_page(tbm, ItemPointerGetBlockNumber(&iptr));
else
tbm_add_tuples(tbm, &iptr, 1, recheck);