Commit b9856b67 authored by Teodor Sigaev's avatar Teodor Sigaev

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.
parent 361bfc35
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -51,7 +51,7 @@ killtuple(Relation r, GISTScanOpaque so, ItemPointer iptr) ...@@ -51,7 +51,7 @@ killtuple(Relation r, GISTScanOpaque so, ItemPointer iptr)
for (offset = FirstOffsetNumber; offset <= maxoff; offset = OffsetNumberNext(offset)) 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)) if (ItemPointerEquals(&(ituple->t_tid), iptr))
{ {
...@@ -139,24 +139,28 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm) ...@@ -139,24 +139,28 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm)
if ( so->qual_ok == false ) if ( so->qual_ok == false )
return 0; return 0;
if (ItemPointerIsValid(&so->curpos) == false) if ( so->curbuf == InvalidBuffer )
{ {
/* Being asked to fetch the first entry, so start at the root */ if (ItemPointerIsValid(&so->curpos) == false)
Assert(so->curbuf == InvalidBuffer); {
Assert(so->stack == NULL); /* Being asked to fetch the first entry, so start at the root */
Assert(so->curbuf == InvalidBuffer);
Assert(so->stack == NULL);
so->curbuf = ReadBuffer(scan->indexRelation, GIST_ROOT_BLKNO); so->curbuf = ReadBuffer(scan->indexRelation, GIST_ROOT_BLKNO);
stk = so->stack = (GISTSearchStack *) palloc0(sizeof(GISTSearchStack)); stk = so->stack = (GISTSearchStack *) palloc0(sizeof(GISTSearchStack));
stk->next = NULL; stk->next = NULL;
stk->block = GIST_ROOT_BLKNO; stk->block = GIST_ROOT_BLKNO;
pgstat_count_index_scan(scan->indexRelation); pgstat_count_index_scan(scan->indexRelation);
} }
else if (so->curbuf == InvalidBuffer) else
{ {
return 0; /* scan is finished */
return 0;
}
} }
/* /*
...@@ -171,8 +175,13 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm) ...@@ -171,8 +175,13 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm)
if ( so->curPageData < so->nPageData ) 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; scan->xs_recheck = so->pageData[ so->curPageData ].recheck;
ItemPointerSet(&so->curpos,
BufferGetBlockNumber(so->curbuf),
so->pageData[ so->curPageData ].pageOffset);
so->curPageData ++; so->curPageData ++;
return 1; return 1;
...@@ -307,8 +316,6 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm) ...@@ -307,8 +316,6 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm)
* return success. Note that we keep "curbuf" pinned so that * return success. Note that we keep "curbuf" pinned so that
* we can efficiently resume the index scan later. * we can efficiently resume the index scan later.
*/ */
ItemPointerSet(&(so->curpos),
BufferGetBlockNumber(so->curbuf), n);
if (!(scan->ignore_killed_tuples && if (!(scan->ignore_killed_tuples &&
ItemIdIsDead(PageGetItemId(p, n)))) ItemIdIsDead(PageGetItemId(p, n))))
...@@ -319,7 +326,8 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm) ...@@ -319,7 +326,8 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm)
tbm_add_tuples(tbm, &it->t_tid, 1, scan->xs_recheck); tbm_add_tuples(tbm, &it->t_tid, 1, scan->xs_recheck);
else 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->pageData[ so->nPageData ].recheck = scan->xs_recheck;
so->nPageData ++; so->nPageData ++;
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 ...@@ -60,7 +60,8 @@ typedef struct GISTSTATE
typedef struct ItemResult typedef struct ItemResult
{ {
ItemPointerData iptr; ItemPointerData heapPtr;
OffsetNumber pageOffset; /* offset in index page */
bool recheck; bool recheck;
} ItemResult; } ItemResult;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment