1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-05 09:19:17 +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:
Teodor Sigaev 2008-10-22 12:55:59 +00:00
parent f189a12226
commit 8a47932c3e
3 changed files with 26 additions and 13 deletions

View File

@ -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.62.2.1 2008/08/23 10:41:38 teodor Exp $ * $PostgreSQL: pgsql/src/backend/access/gist/gistget.c,v 1.62.2.2 2008/10/22 12:55:59 teodor Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -153,7 +153,11 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
{ {
while( ntids < maxtids && so->curPageData < so->nPageData ) 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 ++; so->curPageData ++;
ntids++; ntids++;
@ -247,8 +251,13 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
{ {
while( ntids < maxtids && so->curPageData < so->nPageData ) 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 ++; so->curPageData ++;
ntids++; ntids++;
} }
@ -293,13 +302,11 @@ gistnext(IndexScanDesc scan, ScanDirection dir, ItemPointer tids, int maxtids, b
* we can efficiently resume the index scan later. * we can efficiently resume the index scan later.
*/ */
ItemPointerSet(&(scan->currentItemData),
BufferGetBlockNumber(so->curbuf), n);
if (!(ignore_killed_tuples && ItemIdDeleted(PageGetItemId(p, n)))) if (!(ignore_killed_tuples && ItemIdDeleted(PageGetItemId(p, n))))
{ {
it = (IndexTuple) PageGetItem(p, 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 ++; so->nPageData ++;
} }
} }

View File

@ -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/gistscan.c,v 1.65.2.1 2008/08/23 10:41:38 teodor Exp $ * $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.65.2.2 2008/10/22 12:55:59 teodor Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -154,7 +154,7 @@ gistmarkpos(PG_FUNCTION_ARGS)
so->markNPageData = so->nPageData; so->markNPageData = so->nPageData;
so->markCurPageData = so->curPageData; so->markCurPageData = so->curPageData;
if ( so->markNPageData > 0 ) 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(); PG_RETURN_VOID();
} }
@ -208,7 +208,7 @@ gistrestrpos(PG_FUNCTION_ARGS)
so->nPageData = so->markNPageData; so->nPageData = so->markNPageData;
so->curPageData = so->markNPageData; so->curPageData = so->markNPageData;
if ( so->markNPageData > 0 ) 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(); PG_RETURN_VOID();
} }

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, 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.24.2.1 2008/08/23 10:41:38 teodor Exp $ * $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.24.2.2 2008/10/22 12:55:59 teodor Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -60,6 +60,12 @@ typedef struct GISTSTATE
TupleDesc tupdesc; TupleDesc tupdesc;
} GISTSTATE; } 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 * When we're doing a scan, we need to keep track of the parent stack
* for the marked and current items. * for the marked and current items.
@ -74,10 +80,10 @@ typedef struct GISTScanOpaqueData
Buffer curbuf; Buffer curbuf;
Buffer markbuf; Buffer markbuf;
ItemPointerData pageData[BLCKSZ/sizeof(IndexTupleData)]; MatchedItemPtr pageData[BLCKSZ/sizeof(IndexTupleData)];
OffsetNumber nPageData; OffsetNumber nPageData;
OffsetNumber curPageData; OffsetNumber curPageData;
ItemPointerData markPageData[BLCKSZ/sizeof(IndexTupleData)]; MatchedItemPtr markPageData[BLCKSZ/sizeof(IndexTupleData)];
OffsetNumber markNPageData; OffsetNumber markNPageData;
OffsetNumber markCurPageData; OffsetNumber markCurPageData;
} GISTScanOpaqueData; } GISTScanOpaqueData;