mirror of
https://github.com/postgres/postgres.git
synced 2025-06-30 21:42:05 +03:00
pgindent run for 8.2.
This commit is contained in:
@ -1,14 +1,14 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* ginget.c
|
||||
* fetch tuples from a GIN scan.
|
||||
* fetch tuples from a GIN scan.
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/gin/ginget.c,v 1.2 2006/07/14 14:52:16 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/gin/ginget.c,v 1.3 2006/10/04 00:29:47 momjian Exp $
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -18,15 +18,17 @@
|
||||
#include "utils/memutils.h"
|
||||
|
||||
static OffsetNumber
|
||||
findItemInPage( Page page, ItemPointer item, OffsetNumber off ) {
|
||||
findItemInPage(Page page, ItemPointer item, OffsetNumber off)
|
||||
{
|
||||
OffsetNumber maxoff = GinPageGetOpaque(page)->maxoff;
|
||||
int res;
|
||||
int res;
|
||||
|
||||
for(; off<=maxoff; off++) {
|
||||
res = compareItemPointers( item, (ItemPointer)GinDataPageGetItem(page, off) );
|
||||
Assert( res>= 0 );
|
||||
for (; off <= maxoff; off++)
|
||||
{
|
||||
res = compareItemPointers(item, (ItemPointer) GinDataPageGetItem(page, off));
|
||||
Assert(res >= 0);
|
||||
|
||||
if ( res == 0 )
|
||||
if (res == 0)
|
||||
return off;
|
||||
}
|
||||
|
||||
@ -38,24 +40,29 @@ findItemInPage( Page page, ItemPointer item, OffsetNumber off ) {
|
||||
* Stop* functions unlock buffer (but don't release!)
|
||||
*/
|
||||
static void
|
||||
startScanEntry( Relation index, GinState *ginstate, GinScanEntry entry, bool firstCall ) {
|
||||
if ( entry->master != NULL ) {
|
||||
startScanEntry(Relation index, GinState *ginstate, GinScanEntry entry, bool firstCall)
|
||||
{
|
||||
if (entry->master != NULL)
|
||||
{
|
||||
entry->isFinished = entry->master->isFinished;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( firstCall ) {
|
||||
/* at first call we should find entry, and
|
||||
begin scan of posting tree or just store posting list in memory */
|
||||
if (firstCall)
|
||||
{
|
||||
/*
|
||||
* at first call we should find entry, and begin scan of posting tree
|
||||
* or just store posting list in memory
|
||||
*/
|
||||
GinBtreeData btreeEntry;
|
||||
GinBtreeStack *stackEntry;
|
||||
Page page;
|
||||
bool needUnlock = TRUE;
|
||||
GinBtreeStack *stackEntry;
|
||||
Page page;
|
||||
bool needUnlock = TRUE;
|
||||
|
||||
prepareEntryScan( &btreeEntry, index, entry->entry, ginstate );
|
||||
prepareEntryScan(&btreeEntry, index, entry->entry, ginstate);
|
||||
btreeEntry.searchMode = TRUE;
|
||||
stackEntry = ginFindLeafPage(&btreeEntry, NULL);
|
||||
page = BufferGetPage( stackEntry->buffer );
|
||||
page = BufferGetPage(stackEntry->buffer);
|
||||
|
||||
entry->isFinished = TRUE;
|
||||
entry->buffer = InvalidBuffer;
|
||||
@ -65,103 +72,115 @@ startScanEntry( Relation index, GinState *ginstate, GinScanEntry entry, bool fir
|
||||
entry->reduceResult = FALSE;
|
||||
entry->predictNumberResult = 0;
|
||||
|
||||
if ( btreeEntry.findItem( &btreeEntry, stackEntry ) ) {
|
||||
IndexTuple itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, stackEntry->off));
|
||||
if (btreeEntry.findItem(&btreeEntry, stackEntry))
|
||||
{
|
||||
IndexTuple itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, stackEntry->off));
|
||||
|
||||
if ( GinIsPostingTree(itup) ) {
|
||||
if (GinIsPostingTree(itup))
|
||||
{
|
||||
BlockNumber rootPostingTree = GinGetPostingTree(itup);
|
||||
GinPostingTreeScan *gdi;
|
||||
Page page;
|
||||
Page page;
|
||||
|
||||
LockBuffer(stackEntry->buffer, GIN_UNLOCK);
|
||||
needUnlock = FALSE;
|
||||
gdi = prepareScanPostingTree( index, rootPostingTree, TRUE );
|
||||
needUnlock = FALSE;
|
||||
gdi = prepareScanPostingTree(index, rootPostingTree, TRUE);
|
||||
|
||||
entry->buffer = scanBeginPostingTree( gdi );
|
||||
IncrBufferRefCount( entry->buffer );
|
||||
entry->buffer = scanBeginPostingTree(gdi);
|
||||
IncrBufferRefCount(entry->buffer);
|
||||
|
||||
page = BufferGetPage( entry->buffer );
|
||||
entry->predictNumberResult = gdi->stack->predictNumber * GinPageGetOpaque(page)->maxoff;
|
||||
page = BufferGetPage(entry->buffer);
|
||||
entry->predictNumberResult = gdi->stack->predictNumber * GinPageGetOpaque(page)->maxoff;
|
||||
|
||||
freeGinBtreeStack( gdi->stack );
|
||||
pfree( gdi );
|
||||
freeGinBtreeStack(gdi->stack);
|
||||
pfree(gdi);
|
||||
entry->isFinished = FALSE;
|
||||
} else if ( GinGetNPosting(itup) > 0 ) {
|
||||
}
|
||||
else if (GinGetNPosting(itup) > 0)
|
||||
{
|
||||
entry->nlist = GinGetNPosting(itup);
|
||||
entry->list = (ItemPointerData*)palloc( sizeof(ItemPointerData) * entry->nlist );
|
||||
memcpy( entry->list, GinGetPosting(itup), sizeof(ItemPointerData) * entry->nlist );
|
||||
entry->list = (ItemPointerData *) palloc(sizeof(ItemPointerData) * entry->nlist);
|
||||
memcpy(entry->list, GinGetPosting(itup), sizeof(ItemPointerData) * entry->nlist);
|
||||
entry->isFinished = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( needUnlock )
|
||||
if (needUnlock)
|
||||
LockBuffer(stackEntry->buffer, GIN_UNLOCK);
|
||||
freeGinBtreeStack( stackEntry );
|
||||
} else if ( entry->buffer != InvalidBuffer ) {
|
||||
freeGinBtreeStack(stackEntry);
|
||||
}
|
||||
else if (entry->buffer != InvalidBuffer)
|
||||
{
|
||||
/* we should find place were we was stopped */
|
||||
BlockNumber blkno;
|
||||
Page page;
|
||||
Page page;
|
||||
|
||||
LockBuffer( entry->buffer, GIN_SHARE );
|
||||
LockBuffer(entry->buffer, GIN_SHARE);
|
||||
|
||||
if ( !ItemPointerIsValid( &entry->curItem ) )
|
||||
if (!ItemPointerIsValid(&entry->curItem))
|
||||
/* start position */
|
||||
return;
|
||||
Assert( entry->offset!=InvalidOffsetNumber );
|
||||
Assert(entry->offset != InvalidOffsetNumber);
|
||||
|
||||
page = BufferGetPage( entry->buffer );
|
||||
page = BufferGetPage(entry->buffer);
|
||||
|
||||
/* try to find curItem in current buffer */
|
||||
if ( (entry->offset=findItemInPage(page , &entry->curItem, entry->offset))!=InvalidOffsetNumber )
|
||||
if ((entry->offset = findItemInPage(page, &entry->curItem, entry->offset)) != InvalidOffsetNumber)
|
||||
return;
|
||||
|
||||
/* walk to right */
|
||||
while( (blkno = GinPageGetOpaque( page )->rightlink)!=InvalidBlockNumber ) {
|
||||
LockBuffer( entry->buffer, GIN_UNLOCK );
|
||||
entry->buffer = ReleaseAndReadBuffer( entry->buffer, index, blkno );
|
||||
LockBuffer( entry->buffer, GIN_SHARE );
|
||||
page = BufferGetPage( entry->buffer );
|
||||
while ((blkno = GinPageGetOpaque(page)->rightlink) != InvalidBlockNumber)
|
||||
{
|
||||
LockBuffer(entry->buffer, GIN_UNLOCK);
|
||||
entry->buffer = ReleaseAndReadBuffer(entry->buffer, index, blkno);
|
||||
LockBuffer(entry->buffer, GIN_SHARE);
|
||||
page = BufferGetPage(entry->buffer);
|
||||
|
||||
if ( (entry->offset=findItemInPage(page , &entry->curItem, FirstOffsetNumber))!=InvalidOffsetNumber )
|
||||
if ((entry->offset = findItemInPage(page, &entry->curItem, FirstOffsetNumber)) != InvalidOffsetNumber)
|
||||
return;
|
||||
}
|
||||
|
||||
elog(ERROR,"Logic error: lost previously founded ItemId");
|
||||
elog(ERROR, "Logic error: lost previously founded ItemId");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
stopScanEntry( GinScanEntry entry ) {
|
||||
if ( entry->buffer != InvalidBuffer )
|
||||
LockBuffer( entry->buffer, GIN_UNLOCK );
|
||||
stopScanEntry(GinScanEntry entry)
|
||||
{
|
||||
if (entry->buffer != InvalidBuffer)
|
||||
LockBuffer(entry->buffer, GIN_UNLOCK);
|
||||
}
|
||||
|
||||
static void
|
||||
startScanKey( Relation index, GinState *ginstate, GinScanKey key ) {
|
||||
uint32 i;
|
||||
startScanKey(Relation index, GinState *ginstate, GinScanKey key)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
for(i=0;i<key->nentries;i++)
|
||||
startScanEntry( index, ginstate, key->scanEntry+i, key->firstCall );
|
||||
|
||||
if ( key->firstCall ) {
|
||||
memset( key->entryRes, TRUE, sizeof(bool) * key->nentries );
|
||||
for (i = 0; i < key->nentries; i++)
|
||||
startScanEntry(index, ginstate, key->scanEntry + i, key->firstCall);
|
||||
|
||||
if (key->firstCall)
|
||||
{
|
||||
memset(key->entryRes, TRUE, sizeof(bool) * key->nentries);
|
||||
key->isFinished = FALSE;
|
||||
key->firstCall = FALSE;
|
||||
|
||||
if ( GinFuzzySearchLimit > 0 ) {
|
||||
if (GinFuzzySearchLimit > 0)
|
||||
{
|
||||
/*
|
||||
* If all of keys more than treshold 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 treshold 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++)
|
||||
if ( key->scanEntry[i].predictNumberResult <= key->nentries * GinFuzzySearchLimit )
|
||||
return;
|
||||
|
||||
for(i=0;i<key->nentries;i++)
|
||||
if ( key->scanEntry[i].predictNumberResult > key->nentries * GinFuzzySearchLimit ) {
|
||||
for (i = 0; i < key->nentries; i++)
|
||||
if (key->scanEntry[i].predictNumberResult <= key->nentries * GinFuzzySearchLimit)
|
||||
return;
|
||||
|
||||
for (i = 0; i < key->nentries; i++)
|
||||
if (key->scanEntry[i].predictNumberResult > key->nentries * GinFuzzySearchLimit)
|
||||
{
|
||||
key->scanEntry[i].predictNumberResult /= key->nentries;
|
||||
key->scanEntry[i].reduceResult = TRUE;
|
||||
}
|
||||
@ -170,50 +189,60 @@ startScanKey( Relation index, GinState *ginstate, GinScanKey key ) {
|
||||
}
|
||||
|
||||
static void
|
||||
stopScanKey( GinScanKey key ) {
|
||||
uint32 i;
|
||||
stopScanKey(GinScanKey key)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
for(i=0;i<key->nentries;i++)
|
||||
stopScanEntry( key->scanEntry+i );
|
||||
for (i = 0; i < key->nentries; i++)
|
||||
stopScanEntry(key->scanEntry + i);
|
||||
}
|
||||
|
||||
static void
|
||||
startScan( IndexScanDesc scan ) {
|
||||
uint32 i;
|
||||
GinScanOpaque so = (GinScanOpaque) scan->opaque;
|
||||
startScan(IndexScanDesc scan)
|
||||
{
|
||||
uint32 i;
|
||||
GinScanOpaque so = (GinScanOpaque) scan->opaque;
|
||||
|
||||
for(i=0; i<so->nkeys; i++)
|
||||
startScanKey( scan->indexRelation, &so->ginstate, so->keys + i );
|
||||
for (i = 0; i < so->nkeys; i++)
|
||||
startScanKey(scan->indexRelation, &so->ginstate, so->keys + i);
|
||||
}
|
||||
|
||||
static void
|
||||
stopScan( IndexScanDesc scan ) {
|
||||
uint32 i;
|
||||
GinScanOpaque so = (GinScanOpaque) scan->opaque;
|
||||
stopScan(IndexScanDesc scan)
|
||||
{
|
||||
uint32 i;
|
||||
GinScanOpaque so = (GinScanOpaque) scan->opaque;
|
||||
|
||||
for(i=0; i<so->nkeys; i++)
|
||||
stopScanKey( so->keys + i );
|
||||
for (i = 0; i < so->nkeys; i++)
|
||||
stopScanKey(so->keys + i);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
entryGetNextItem( Relation index, GinScanEntry entry ) {
|
||||
Page page = BufferGetPage( entry->buffer );
|
||||
entryGetNextItem(Relation index, GinScanEntry entry)
|
||||
{
|
||||
Page page = BufferGetPage(entry->buffer);
|
||||
|
||||
entry->offset++;
|
||||
if ( entry->offset <= GinPageGetOpaque( page )->maxoff && GinPageGetOpaque( page )->maxoff >= FirstOffsetNumber ) {
|
||||
entry->curItem = *(ItemPointerData*)GinDataPageGetItem(page, entry->offset);
|
||||
} else {
|
||||
BlockNumber blkno = GinPageGetOpaque( page )->rightlink;
|
||||
|
||||
LockBuffer( entry->buffer, GIN_UNLOCK );
|
||||
if ( blkno == InvalidBlockNumber ) {
|
||||
ReleaseBuffer( entry->buffer );
|
||||
if (entry->offset <= GinPageGetOpaque(page)->maxoff && GinPageGetOpaque(page)->maxoff >= FirstOffsetNumber)
|
||||
{
|
||||
entry->curItem = *(ItemPointerData *) GinDataPageGetItem(page, entry->offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockNumber blkno = GinPageGetOpaque(page)->rightlink;
|
||||
|
||||
LockBuffer(entry->buffer, GIN_UNLOCK);
|
||||
if (blkno == InvalidBlockNumber)
|
||||
{
|
||||
ReleaseBuffer(entry->buffer);
|
||||
entry->buffer = InvalidBuffer;
|
||||
entry->isFinished = TRUE;
|
||||
} else {
|
||||
entry->buffer = ReleaseAndReadBuffer( entry->buffer, index, blkno );
|
||||
LockBuffer( entry->buffer, GIN_SHARE );
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->buffer = ReleaseAndReadBuffer(entry->buffer, index, blkno);
|
||||
LockBuffer(entry->buffer, GIN_SHARE);
|
||||
entry->offset = InvalidOffsetNumber;
|
||||
entryGetNextItem(index, entry);
|
||||
}
|
||||
@ -221,29 +250,37 @@ entryGetNextItem( Relation index, GinScanEntry entry ) {
|
||||
}
|
||||
|
||||
#define gin_rand() (((double) random()) / ((double) MAX_RANDOM_VALUE))
|
||||
#define dropItem(e) ( gin_rand() > ((double)GinFuzzySearchLimit)/((double)((e)->predictNumberResult)) )
|
||||
#define dropItem(e) ( gin_rand() > ((double)GinFuzzySearchLimit)/((double)((e)->predictNumberResult)) )
|
||||
|
||||
/*
|
||||
* Sets entry->curItem to new found heap item pointer for one
|
||||
* Sets entry->curItem to new found heap item pointer for one
|
||||
* entry of one scan key
|
||||
*/
|
||||
static bool
|
||||
entryGetItem( Relation index, GinScanEntry entry ) {
|
||||
if ( entry->master ) {
|
||||
entryGetItem(Relation index, GinScanEntry entry)
|
||||
{
|
||||
if (entry->master)
|
||||
{
|
||||
entry->isFinished = entry->master->isFinished;
|
||||
entry->curItem = entry->master->curItem;
|
||||
} else if ( entry->list ) {
|
||||
}
|
||||
else if (entry->list)
|
||||
{
|
||||
entry->offset++;
|
||||
if ( entry->offset <= entry->nlist )
|
||||
entry->curItem = entry->list[ entry->offset - 1 ];
|
||||
else {
|
||||
ItemPointerSet( &entry->curItem, InvalidBlockNumber, InvalidOffsetNumber );
|
||||
if (entry->offset <= entry->nlist)
|
||||
entry->curItem = entry->list[entry->offset - 1];
|
||||
else
|
||||
{
|
||||
ItemPointerSet(&entry->curItem, InvalidBlockNumber, InvalidOffsetNumber);
|
||||
entry->isFinished = TRUE;
|
||||
}
|
||||
} else {
|
||||
do {
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
entryGetNextItem(index, entry);
|
||||
} while ( entry->isFinished == FALSE && entry->reduceResult == TRUE && dropItem(entry) );
|
||||
} while (entry->isFinished == FALSE && entry->reduceResult == TRUE && dropItem(entry));
|
||||
}
|
||||
|
||||
return entry->isFinished;
|
||||
@ -254,155 +291,180 @@ entryGetItem( Relation index, GinScanEntry entry ) {
|
||||
* returns isFinished!
|
||||
*/
|
||||
static bool
|
||||
keyGetItem( Relation index, GinState *ginstate, MemoryContext tempCtx, GinScanKey key ) {
|
||||
uint32 i;
|
||||
GinScanEntry entry;
|
||||
bool res;
|
||||
MemoryContext oldCtx;
|
||||
keyGetItem(Relation index, GinState *ginstate, MemoryContext tempCtx, GinScanKey key)
|
||||
{
|
||||
uint32 i;
|
||||
GinScanEntry entry;
|
||||
bool res;
|
||||
MemoryContext oldCtx;
|
||||
|
||||
if ( key->isFinished )
|
||||
if (key->isFinished)
|
||||
return TRUE;
|
||||
|
||||
do {
|
||||
/* move forward from previously value and set new curItem,
|
||||
which is minimal from entries->curItems */
|
||||
ItemPointerSetMax( &key->curItem );
|
||||
for(i=0;i<key->nentries;i++) {
|
||||
entry = key->scanEntry+i;
|
||||
|
||||
if ( key->entryRes[i] ) {
|
||||
if ( entry->isFinished == FALSE && entryGetItem(index, entry) == FALSE ) {
|
||||
if (compareItemPointers( &entry->curItem, &key->curItem ) < 0)
|
||||
do
|
||||
{
|
||||
/*
|
||||
* move forward from previously value and set new curItem, which is
|
||||
* minimal from entries->curItems
|
||||
*/
|
||||
ItemPointerSetMax(&key->curItem);
|
||||
for (i = 0; i < key->nentries; i++)
|
||||
{
|
||||
entry = key->scanEntry + i;
|
||||
|
||||
if (key->entryRes[i])
|
||||
{
|
||||
if (entry->isFinished == FALSE && entryGetItem(index, entry) == FALSE)
|
||||
{
|
||||
if (compareItemPointers(&entry->curItem, &key->curItem) < 0)
|
||||
key->curItem = entry->curItem;
|
||||
} else
|
||||
}
|
||||
else
|
||||
key->entryRes[i] = FALSE;
|
||||
} else if ( entry->isFinished == FALSE ) {
|
||||
if (compareItemPointers( &entry->curItem, &key->curItem ) < 0)
|
||||
}
|
||||
else if (entry->isFinished == FALSE)
|
||||
{
|
||||
if (compareItemPointers(&entry->curItem, &key->curItem) < 0)
|
||||
key->curItem = entry->curItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ItemPointerIsMax( &key->curItem ) ) {
|
||||
if (ItemPointerIsMax(&key->curItem))
|
||||
{
|
||||
/* all entries are finished */
|
||||
key->isFinished = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ( key->nentries == 1 ) {
|
||||
|
||||
if (key->nentries == 1)
|
||||
{
|
||||
/* we can do not call consistentFn !! */
|
||||
key->entryRes[0] = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* setting up array for consistentFn */
|
||||
for(i=0;i<key->nentries;i++) {
|
||||
entry = key->scanEntry+i;
|
||||
|
||||
if ( entry->isFinished == FALSE && compareItemPointers( &entry->curItem, &key->curItem )==0 )
|
||||
for (i = 0; i < key->nentries; i++)
|
||||
{
|
||||
entry = key->scanEntry + i;
|
||||
|
||||
if (entry->isFinished == FALSE && compareItemPointers(&entry->curItem, &key->curItem) == 0)
|
||||
key->entryRes[i] = TRUE;
|
||||
else
|
||||
key->entryRes[i] = FALSE;
|
||||
}
|
||||
|
||||
oldCtx = MemoryContextSwitchTo(tempCtx);
|
||||
res = DatumGetBool( FunctionCall3(
|
||||
&ginstate->consistentFn,
|
||||
PointerGetDatum( key->entryRes ),
|
||||
UInt16GetDatum( key->strategy ),
|
||||
key->query
|
||||
));
|
||||
res = DatumGetBool(FunctionCall3(
|
||||
&ginstate->consistentFn,
|
||||
PointerGetDatum(key->entryRes),
|
||||
UInt16GetDatum(key->strategy),
|
||||
key->query
|
||||
));
|
||||
MemoryContextSwitchTo(oldCtx);
|
||||
MemoryContextReset(tempCtx);
|
||||
} while( !res );
|
||||
|
||||
} while (!res);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get heap item pointer from scan
|
||||
* returns true if found
|
||||
* Get heap item pointer from scan
|
||||
* returns true if found
|
||||
*/
|
||||
static bool
|
||||
scanGetItem( IndexScanDesc scan, ItemPointerData *item ) {
|
||||
uint32 i;
|
||||
GinScanOpaque so = (GinScanOpaque) scan->opaque;
|
||||
scanGetItem(IndexScanDesc scan, ItemPointerData *item)
|
||||
{
|
||||
uint32 i;
|
||||
GinScanOpaque so = (GinScanOpaque) scan->opaque;
|
||||
|
||||
ItemPointerSetMin( item );
|
||||
for(i=0;i<so->nkeys;i++) {
|
||||
GinScanKey key = so->keys+i;
|
||||
ItemPointerSetMin(item);
|
||||
for (i = 0; i < so->nkeys; i++)
|
||||
{
|
||||
GinScanKey key = so->keys + i;
|
||||
|
||||
if ( keyGetItem( scan->indexRelation, &so->ginstate, so->tempCtx, key )==FALSE ) {
|
||||
if ( compareItemPointers( item, &key->curItem ) < 0 )
|
||||
if (keyGetItem(scan->indexRelation, &so->ginstate, so->tempCtx, key) == FALSE)
|
||||
{
|
||||
if (compareItemPointers(item, &key->curItem) < 0)
|
||||
*item = key->curItem;
|
||||
} else
|
||||
return FALSE; /* finshed one of keys */
|
||||
}
|
||||
else
|
||||
return FALSE; /* finshed one of keys */
|
||||
}
|
||||
|
||||
for(i=1;i<=so->nkeys;i++) {
|
||||
GinScanKey key = so->keys+i-1;
|
||||
|
||||
for(;;) {
|
||||
int cmp = compareItemPointers( item, &key->curItem );
|
||||
for (i = 1; i <= so->nkeys; i++)
|
||||
{
|
||||
GinScanKey key = so->keys + i - 1;
|
||||
|
||||
if ( cmp == 0 )
|
||||
for (;;)
|
||||
{
|
||||
int cmp = compareItemPointers(item, &key->curItem);
|
||||
|
||||
if (cmp == 0)
|
||||
break;
|
||||
else if ( cmp > 0 ) {
|
||||
if ( keyGetItem( scan->indexRelation, &so->ginstate, so->tempCtx, key )==TRUE )
|
||||
return FALSE; /* finshed one of keys */
|
||||
} else { /* returns to begin */
|
||||
else if (cmp > 0)
|
||||
{
|
||||
if (keyGetItem(scan->indexRelation, &so->ginstate, so->tempCtx, key) == TRUE)
|
||||
return FALSE; /* finshed one of keys */
|
||||
}
|
||||
else
|
||||
{ /* returns to begin */
|
||||
*item = key->curItem;
|
||||
i=0;
|
||||
i = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define GinIsNewKey(s) ( ((GinScanOpaque) scan->opaque)->keys == NULL )
|
||||
|
||||
Datum
|
||||
gingetmulti(PG_FUNCTION_ARGS) {
|
||||
IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
|
||||
Datum
|
||||
gingetmulti(PG_FUNCTION_ARGS)
|
||||
{
|
||||
IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
|
||||
ItemPointer tids = (ItemPointer) PG_GETARG_POINTER(1);
|
||||
int32 max_tids = PG_GETARG_INT32(2);
|
||||
int32 *returned_tids = (int32 *) PG_GETARG_POINTER(3);
|
||||
int32 max_tids = PG_GETARG_INT32(2);
|
||||
int32 *returned_tids = (int32 *) PG_GETARG_POINTER(3);
|
||||
|
||||
if ( GinIsNewKey(scan) )
|
||||
newScanKey( scan );
|
||||
if (GinIsNewKey(scan))
|
||||
newScanKey(scan);
|
||||
|
||||
startScan( scan );
|
||||
startScan(scan);
|
||||
|
||||
*returned_tids = 0;
|
||||
|
||||
do {
|
||||
if ( scanGetItem( scan, tids + *returned_tids ) )
|
||||
do
|
||||
{
|
||||
if (scanGetItem(scan, tids + *returned_tids))
|
||||
(*returned_tids)++;
|
||||
else
|
||||
break;
|
||||
} while ( *returned_tids < max_tids );
|
||||
} while (*returned_tids < max_tids);
|
||||
|
||||
stopScan( scan );
|
||||
stopScan(scan);
|
||||
|
||||
PG_RETURN_BOOL(*returned_tids == max_tids);
|
||||
}
|
||||
|
||||
Datum
|
||||
gingettuple(PG_FUNCTION_ARGS) {
|
||||
gingettuple(PG_FUNCTION_ARGS)
|
||||
{
|
||||
IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
|
||||
ScanDirection dir = (ScanDirection) PG_GETARG_INT32(1);
|
||||
bool res;
|
||||
bool res;
|
||||
|
||||
if ( dir != ForwardScanDirection )
|
||||
if (dir != ForwardScanDirection)
|
||||
elog(ERROR, "Gin doesn't support other scan directions than forward");
|
||||
|
||||
if ( GinIsNewKey(scan) )
|
||||
newScanKey( scan );
|
||||
|
||||
startScan( scan );
|
||||
if (GinIsNewKey(scan))
|
||||
newScanKey(scan);
|
||||
|
||||
startScan(scan);
|
||||
res = scanGetItem(scan, &scan->xs_ctup.t_self);
|
||||
stopScan( scan );
|
||||
stopScan(scan);
|
||||
|
||||
PG_RETURN_BOOL(res);
|
||||
}
|
||||
|
Reference in New Issue
Block a user