aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/gist/gistscan.c
diff options
context:
space:
mode:
authorTeodor Sigaev <teodor@sigaev.ru>2008-08-23 10:41:38 +0000
committerTeodor Sigaev <teodor@sigaev.ru>2008-08-23 10:41:38 +0000
commite41417571307cbf1f019525a3a7d3bf98e7c4603 (patch)
tree8af7e63e2d40d4ed9361980a55c92f65ec085c59 /src/backend/access/gist/gistscan.c
parent7ddd8396479a11ff81b0ca506e97617c4cd445d3 (diff)
downloadpostgresql-e41417571307cbf1f019525a3a7d3bf98e7c4603.tar.gz
postgresql-e41417571307cbf1f019525a3a7d3bf98e7c4603.zip
Fix possible duplicate tuples while GiST scan. Now page is processed
at once and ItemPointers are collected in memory. Remove tuple's killing by killtuple() if tuple was moved to another page - it could produce unaceptable overhead. Backpatch up to 8.1 because the bug was introduced by GiST's concurrency support.
Diffstat (limited to 'src/backend/access/gist/gistscan.c')
-rw-r--r--src/backend/access/gist/gistscan.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c
index b0fdb740047..4864fd1248d 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 2006/10/04 00:29:48 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.65.2.1 2008/08/23 10:41:38 teodor Exp $
*
*-------------------------------------------------------------------------
*/
@@ -67,6 +67,7 @@ gistrescan(PG_FUNCTION_ARGS)
ReleaseBuffer(so->markbuf);
so->markbuf = InvalidBuffer;
}
+
}
else
{
@@ -82,6 +83,8 @@ gistrescan(PG_FUNCTION_ARGS)
scan->opaque = so;
}
+ so->nPageData = so->curPageData = 0;
+
/* Update scan key, if a new one is given */
if (key && scan->numberOfKeys > 0)
{
@@ -148,6 +151,11 @@ gistmarkpos(PG_FUNCTION_ARGS)
so->markbuf = so->curbuf;
}
+ so->markNPageData = so->nPageData;
+ so->markCurPageData = so->curPageData;
+ if ( so->markNPageData > 0 )
+ memcpy( so->markPageData, so->pageData, sizeof(ItemPointerData) * so->markNPageData );
+
PG_RETURN_VOID();
}
@@ -197,6 +205,11 @@ gistrestrpos(PG_FUNCTION_ARGS)
so->curbuf = so->markbuf;
}
+ so->nPageData = so->markNPageData;
+ so->curPageData = so->markNPageData;
+ if ( so->markNPageData > 0 )
+ memcpy( so->pageData, so->markPageData, sizeof(ItemPointerData) * so->markNPageData );
+
PG_RETURN_VOID();
}