mirror of
https://github.com/postgres/postgres.git
synced 2025-06-13 07:41:39 +03:00
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:
@ -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.78 2008/10/20 16:35:14 teodor Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gistget.c,v 1.79 2008/10/22 12:53:56 teodor Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -139,6 +139,8 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm)
|
||||
if ( so->qual_ok == false )
|
||||
return 0;
|
||||
|
||||
if ( so->curbuf == InvalidBuffer )
|
||||
{
|
||||
if (ItemPointerIsValid(&so->curpos) == false)
|
||||
{
|
||||
/* Being asked to fetch the first entry, so start at the root */
|
||||
@ -154,10 +156,12 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm)
|
||||
|
||||
pgstat_count_index_scan(scan->indexRelation);
|
||||
}
|
||||
else if (so->curbuf == InvalidBuffer)
|
||||
else
|
||||
{
|
||||
/* scan is finished */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check stored pointers from last visit
|
||||
@ -171,8 +175,13 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm)
|
||||
|
||||
if ( so->curPageData < so->nPageData )
|
||||
{
|
||||
scan->xs_ctup.t_self = so->pageData[ so->curPageData ].iptr;
|
||||
scan->xs_ctup.t_self = so->pageData[ so->curPageData ].heapPtr;
|
||||
scan->xs_recheck = so->pageData[ so->curPageData ].recheck;
|
||||
|
||||
ItemPointerSet(&so->curpos,
|
||||
BufferGetBlockNumber(so->curbuf),
|
||||
so->pageData[ so->curPageData ].pageOffset);
|
||||
|
||||
so->curPageData ++;
|
||||
|
||||
return 1;
|
||||
@ -307,8 +316,6 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm)
|
||||
* return success. Note that we keep "curbuf" pinned so that
|
||||
* we can efficiently resume the index scan later.
|
||||
*/
|
||||
ItemPointerSet(&(so->curpos),
|
||||
BufferGetBlockNumber(so->curbuf), n);
|
||||
|
||||
if (!(scan->ignore_killed_tuples &&
|
||||
ItemIdIsDead(PageGetItemId(p, n))))
|
||||
@ -319,7 +326,8 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm)
|
||||
tbm_add_tuples(tbm, &it->t_tid, 1, scan->xs_recheck);
|
||||
else
|
||||
{
|
||||
so->pageData[ so->nPageData ].iptr = it->t_tid;
|
||||
so->pageData[ so->nPageData ].heapPtr = it->t_tid;
|
||||
so->pageData[ so->nPageData ].pageOffset = n;
|
||||
so->pageData[ so->nPageData ].recheck = scan->xs_recheck;
|
||||
so->nPageData ++;
|
||||
}
|
||||
|
@ -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.34 2008/10/20 13:39:44 teodor Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.35 2008/10/22 12:53:56 teodor Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -60,7 +60,8 @@ typedef struct GISTSTATE
|
||||
|
||||
typedef struct ItemResult
|
||||
{
|
||||
ItemPointerData iptr;
|
||||
ItemPointerData heapPtr;
|
||||
OffsetNumber pageOffset; /* offset in index page */
|
||||
bool recheck;
|
||||
} ItemResult;
|
||||
|
||||
|
Reference in New Issue
Block a user