Fix GiST's killing tuple: GISTScanOpaque->curpos wasn't
correctly set. As result, killtuple() marks as dead wrong tuple on page. Bug was introduced by me while fixing possible duplicates during GiST index scan.
This commit is contained in:
parent
6a112282b9
commit
666aad267b
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gistget.c,v 1.69.2.2 2008/10/17 17:02:42 teodor Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gistget.c,v 1.69.2.3 2008/10/22 12:54:25 teodor Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -49,7 +49,7 @@ killtuple(Relation r, GISTScanOpaque so, ItemPointer iptr)
|
||||
|
||||
for (offset = FirstOffsetNumber; offset <= maxoff; offset = OffsetNumberNext(offset))
|
||||
{
|
||||
IndexTuple ituple = (IndexTuple) PageGetItem(p, PageGetItemId(p, offset));
|
||||
IndexTuple ituple = (IndexTuple) PageGetItem(p, PageGetItemId(p, offset));
|
||||
|
||||
if (ItemPointerEquals(&(ituple->t_tid), iptr))
|
||||
{
|
||||
@ -157,7 +157,11 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids,
|
||||
{
|
||||
while( ntids < maxtids && so->curPageData < so->nPageData )
|
||||
{
|
||||
tids[ ntids ] = scan->xs_ctup.t_self = so->pageData[ so->curPageData ];
|
||||
tids[ ntids ] = scan->xs_ctup.t_self = so->pageData[ so->curPageData ].heapPtr;
|
||||
ItemPointerSet(&(so->curpos),
|
||||
BufferGetBlockNumber(so->curbuf),
|
||||
so->pageData[ so->curPageData ].pageOffset);
|
||||
|
||||
|
||||
so->curPageData ++;
|
||||
ntids++;
|
||||
@ -251,8 +255,13 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids,
|
||||
{
|
||||
while( ntids < maxtids && so->curPageData < so->nPageData )
|
||||
{
|
||||
tids[ ntids ] = scan->xs_ctup.t_self = so->pageData[ so->curPageData ];
|
||||
tids[ ntids ] = scan->xs_ctup.t_self =
|
||||
so->pageData[ so->curPageData ].heapPtr;
|
||||
|
||||
ItemPointerSet(&(so->curpos),
|
||||
BufferGetBlockNumber(so->curbuf),
|
||||
so->pageData[ so->curPageData ].pageOffset);
|
||||
|
||||
so->curPageData ++;
|
||||
ntids++;
|
||||
}
|
||||
@ -297,13 +306,11 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids,
|
||||
* we can efficiently resume the index scan later.
|
||||
*/
|
||||
|
||||
ItemPointerSet(&(so->curpos),
|
||||
BufferGetBlockNumber(so->curbuf), n);
|
||||
|
||||
if (!(ignore_killed_tuples && ItemIdIsDead(PageGetItemId(p, n))))
|
||||
{
|
||||
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
|
||||
so->pageData[ so->nPageData ] = it->t_tid;
|
||||
so->pageData[ so->nPageData ].heapPtr = it->t_tid;
|
||||
so->pageData[ so->nPageData ].pageOffset = n;
|
||||
so->nPageData ++;
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.68.2.2 2008/10/17 17:02:42 teodor Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.68.2.3 2008/10/22 12:54:25 teodor Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -163,7 +163,7 @@ gistmarkpos(PG_FUNCTION_ARGS)
|
||||
so->markNPageData = so->nPageData;
|
||||
so->markCurPageData = so->curPageData;
|
||||
if ( so->markNPageData > 0 )
|
||||
memcpy( so->markPageData, so->pageData, sizeof(ItemPointerData) * so->markNPageData );
|
||||
memcpy( so->markPageData, so->pageData, sizeof(MatchedItemPtr) * so->markNPageData );
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
@ -217,7 +217,7 @@ gistrestrpos(PG_FUNCTION_ARGS)
|
||||
so->nPageData = so->markNPageData;
|
||||
so->curPageData = so->markNPageData;
|
||||
if ( so->markNPageData > 0 )
|
||||
memcpy( so->pageData, so->markPageData, sizeof(ItemPointerData) * so->markNPageData );
|
||||
memcpy( so->pageData, so->markPageData, sizeof(MatchedItemPtr) * so->markNPageData );
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.28.2.2 2008/10/17 17:02:42 teodor Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.28.2.3 2008/10/22 12:54:25 teodor Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -60,6 +60,12 @@ typedef struct GISTSTATE
|
||||
TupleDesc tupdesc;
|
||||
} GISTSTATE;
|
||||
|
||||
typedef struct MatchedItemPtr
|
||||
{
|
||||
ItemPointerData heapPtr;
|
||||
OffsetNumber pageOffset; /* offset in index page */
|
||||
} MatchedItemPtr;
|
||||
|
||||
/*
|
||||
* When we're doing a scan, we need to keep track of the parent stack
|
||||
* for the marked and current items.
|
||||
@ -77,10 +83,10 @@ typedef struct GISTScanOpaqueData
|
||||
Buffer markbuf;
|
||||
ItemPointerData markpos;
|
||||
|
||||
ItemPointerData pageData[BLCKSZ/sizeof(IndexTupleData)];
|
||||
MatchedItemPtr pageData[BLCKSZ/sizeof(IndexTupleData)];
|
||||
OffsetNumber nPageData;
|
||||
OffsetNumber curPageData;
|
||||
ItemPointerData markPageData[BLCKSZ/sizeof(IndexTupleData)];
|
||||
MatchedItemPtr markPageData[BLCKSZ/sizeof(IndexTupleData)];
|
||||
OffsetNumber markNPageData;
|
||||
OffsetNumber markCurPageData;
|
||||
} GISTScanOpaqueData;
|
||||
|
Loading…
x
Reference in New Issue
Block a user