diff options
author | Teodor Sigaev <teodor@sigaev.ru> | 2008-10-22 12:56:25 +0000 |
---|---|---|
committer | Teodor Sigaev <teodor@sigaev.ru> | 2008-10-22 12:56:25 +0000 |
commit | b5f5c89528a39a4b9b3b8c862fb73a0131b98688 (patch) | |
tree | 4cc9977976557baf886de7827f8c4befb2b920c6 /src | |
parent | feb45966970e6aa6cfdb2a42eaa0cba8472d94fb (diff) | |
download | postgresql-b5f5c89528a39a4b9b3b8c862fb73a0131b98688.tar.gz postgresql-b5f5c89528a39a4b9b3b8c862fb73a0131b98688.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/access/gist/gistget.c | 21 | ||||
-rw-r--r-- | src/backend/access/gist/gistscan.c | 6 | ||||
-rw-r--r-- | src/include/access/gist_private.h | 12 |
3 files changed, 26 insertions, 13 deletions
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c index feeb84d38d7..7c041f480bf 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.52.2.2 2008/08/23 10:43:58 teodor Exp $ + * $PostgreSQL: pgsql/src/backend/access/gist/gistget.c,v 1.52.2.3 2008/10/22 12:56:25 teodor Exp $ * *------------------------------------------------------------------------- */ @@ -153,7 +153,11 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b { 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(&scan->currentItemData, + BufferGetBlockNumber(so->curbuf), + so->pageData[ so->curPageData ].pageOffset); + so->curPageData ++; ntids++; @@ -246,8 +250,13 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b { 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(&scan->currentItemData, + BufferGetBlockNumber(so->curbuf), + so->pageData[ so->curPageData ].pageOffset); + so->curPageData ++; ntids++; } @@ -291,13 +300,11 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b * we can efficiently resume the index scan later. */ - ItemPointerSet(&(scan->currentItemData), - BufferGetBlockNumber(so->curbuf), n); - if (!(ignore_killed_tuples && ItemIdDeleted(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 ++; } } diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c index 3604debba0f..4ee82d13f59 100644 --- a/src/backend/access/gist/gistscan.c +++ b/src/backend/access/gist/gistscan.c @@ -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.61.2.1 2008/08/23 10:43:58 teodor Exp $ + * $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.61.2.2 2008/10/22 12:56:25 teodor Exp $ * *------------------------------------------------------------------------- */ @@ -185,7 +185,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(); } @@ -239,7 +239,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(); } diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h index c1861180d24..1668f80a9c9 100644 --- a/src/include/access/gist_private.h +++ b/src/include/access/gist_private.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.8.2.1 2008/08/23 10:43:58 teodor Exp $ + * $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.8.2.2 2008/10/22 12:56: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. @@ -74,10 +80,10 @@ typedef struct GISTScanOpaqueData Buffer curbuf; Buffer markbuf; - 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; |