aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTeodor Sigaev <teodor@sigaev.ru>2008-10-22 12:55:59 +0000
committerTeodor Sigaev <teodor@sigaev.ru>2008-10-22 12:55:59 +0000
commit8a47932c3ea47f1dce8df10dfc424a199ada9110 (patch)
treed6654ca2fe4dac52264b4c66eabdf79cca6f3f55 /src
parentf189a122265a964cdd7f5ce44447afb9f45f1aa0 (diff)
downloadpostgresql-8a47932c3ea47f1dce8df10dfc424a199ada9110.tar.gz
postgresql-8a47932c3ea47f1dce8df10dfc424a199ada9110.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.c21
-rw-r--r--src/backend/access/gist/gistscan.c6
-rw-r--r--src/include/access/gist_private.h12
3 files changed, 26 insertions, 13 deletions
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index ebc41185cbc..ea4d06c232d 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.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 )
{
- 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++;
@@ -247,8 +251,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++;
}
@@ -293,13 +302,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 4864fd1248d..aeb1a8282c8 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.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->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();
}
@@ -208,7 +208,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 ee94875a342..cab33bc9b60 100644
--- a/src/include/access/gist_private.h
+++ b/src/include/access/gist_private.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* 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;
} 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;