From: Teodor Sigaev Date: Wed, 22 Oct 2008 12:53:56 +0000 (+0000) Subject: Fix GiST's killing tuple: GISTScanOpaque->curpos wasn't X-Git-Tag: REL8_4_BETA1~839 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b9856b67a7a762ab5bedfafbda4f654797d83996;p=postgresql 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. --- diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c index 50d5fc21a4..c7d14ecf23 100644 --- a/src/backend/access/gist/gistget.c +++ b/src/backend/access/gist/gistget.c @@ -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 $ * *------------------------------------------------------------------------- */ @@ -51,7 +51,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)) { @@ -139,24 +139,28 @@ gistnext(IndexScanDesc scan, TIDBitmap *tbm) if ( so->qual_ok == false ) return 0; - if (ItemPointerIsValid(&so->curpos) == false) + if ( so->curbuf == InvalidBuffer ) { - /* Being asked to fetch the first entry, so start at the root */ - Assert(so->curbuf == InvalidBuffer); - Assert(so->stack == NULL); + if (ItemPointerIsValid(&so->curpos) == false) + { + /* 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->block = GIST_ROOT_BLKNO; + stk->next = NULL; + stk->block = GIST_ROOT_BLKNO; - pgstat_count_index_scan(scan->indexRelation); - } - else if (so->curbuf == InvalidBuffer) - { - return 0; + pgstat_count_index_scan(scan->indexRelation); + } + else + { + /* scan is finished */ + return 0; + } } /* @@ -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 ++; } diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h index 2d942e54b4..42f9bc7636 100644 --- a/src/include/access/gist_private.h +++ b/src/include/access/gist_private.h @@ -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;