aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeodor Sigaev <teodor@sigaev.ru>2005-08-30 08:36:52 +0000
committerTeodor Sigaev <teodor@sigaev.ru>2005-08-30 08:36:52 +0000
commitd4235f9f18160c160a088c4ded9f953420146147 (patch)
tree6a080c33bff51a5a190440ebef516c3bdfc47ab2
parent2ba05400242c31604c14a1d0276abeabc7d7ed77 (diff)
downloadpostgresql-d4235f9f18160c160a088c4ded9f953420146147.tar.gz
postgresql-d4235f9f18160c160a088c4ded9f953420146147.zip
Fix missing rows in query
update a=.. where a... with GiST index on column 'a' Backpatch from 8.0 branch
-rw-r--r--src/backend/access/gist/gist.c7
-rw-r--r--src/backend/access/gist/gistget.c18
-rw-r--r--src/backend/access/gist/gistscan.c38
3 files changed, 43 insertions, 20 deletions
diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c
index 2f990ec05ed..4d595ca9877 100644
--- a/src/backend/access/gist/gist.c
+++ b/src/backend/access/gist/gist.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.105 2003/08/04 02:39:56 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.105.4.1 2005/08/30 08:36:52 teodor Exp $
*
*-------------------------------------------------------------------------
*/
@@ -502,7 +502,7 @@ gistlayerinsert(Relation r, BlockNumber blkno,
* changed beginning from 'child' offset
*/
if (ret & SPLITED)
- gistadjscans(r, GISTOP_SPLIT, blkno, child);
+ gistadjscans(r, GISTOP_SPLIT, nblkno, FirstOffsetNumber);
}
ret = INSERTED;
@@ -1435,6 +1435,9 @@ gistnewroot(Relation r, IndexTuple *itup, int len)
Page p;
b = ReadBuffer(r, GISTP_ROOT);
+
+ gistadjscans(r, GISTOP_SPLIT, GISTP_ROOT, FirstOffsetNumber);
+
GISTInitBuffer(b, 0);
p = BufferGetPage(b);
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index 596c11e41e8..63b09a961f4 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
- * $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.36.4.1 2004/08/27 17:47:56 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.36.4.2 2005/08/30 08:36:52 teodor Exp $
*
*-------------------------------------------------------------------------
*/
@@ -167,10 +167,18 @@ gistnext(IndexScanDesc s, ScanDirection dir)
maxoff = PageGetMaxOffsetNumber(p);
po = (GISTPageOpaque) PageGetSpecialPointer(p);
- if (ScanDirectionIsBackward(dir))
- n = OffsetNumberPrev(stk->gs_child);
- else
- n = OffsetNumberNext(stk->gs_child);
+ if ( stk->gs_child == InvalidOffsetNumber ) {
+ /* rescan page */
+ if (ScanDirectionIsBackward(dir))
+ n = PageGetMaxOffsetNumber(p);
+ else
+ n = FirstOffsetNumber;
+ } else {
+ if (ScanDirectionIsBackward(dir))
+ n = OffsetNumberPrev(stk->gs_child);
+ else
+ n = OffsetNumberNext(stk->gs_child);
+ }
so->s_stack = stk->gs_parent;
pfree(stk);
diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c
index 790048aef38..9616d4d19c2 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
- * $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.47 2003/08/04 02:39:57 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.47.4.1 2005/08/30 08:36:52 teodor Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,7 +24,7 @@ static void gistregscan(IndexScanDesc s);
static void gistdropscan(IndexScanDesc s);
static void gistadjone(IndexScanDesc s, int op, BlockNumber blkno,
OffsetNumber offnum);
-static void adjuststack(GISTSTACK *stk, BlockNumber blkno);
+static void adjuststack(GISTSTACK *stk, int op,BlockNumber blkno, OffsetNumber offnum);
static void adjustiptr(IndexScanDesc s, ItemPointer iptr,
int op, BlockNumber blkno, OffsetNumber offnum);
@@ -313,11 +313,8 @@ gistadjone(IndexScanDesc s,
so = (GISTScanOpaque) s->opaque;
- if (op == GISTOP_SPLIT)
- {
- adjuststack(so->s_stack, blkno);
- adjuststack(so->s_markstk, blkno);
- }
+ adjuststack(so->s_stack, op, blkno, offnum);
+ adjuststack(so->s_markstk, op, blkno, offnum);
}
/*
@@ -399,16 +396,31 @@ adjustiptr(IndexScanDesc s,
* access method update code for heaps; if we've modified the tuple we
* are looking at already in this transaction, we ignore the update
* request.
+ * If index tuple on our parent stack has been deleted, we need
+ * to make step back to avoid miss.
*/
-/*ARGSUSED*/
static void
-adjuststack(GISTSTACK *stk,
- BlockNumber blkno)
+adjuststack(GISTSTACK *stk, int op, BlockNumber blkno, OffsetNumber offnum)
{
- while (stk != (GISTSTACK *) NULL)
+ while (stk != NULL)
{
- if (stk->gs_blk == blkno)
- stk->gs_child = FirstOffsetNumber;
+ if (stk->gs_blk == blkno) {
+ switch (op) {
+ case GISTOP_DEL:
+ if ( stk->gs_child >= offnum ) {
+ if ( stk->gs_child > FirstOffsetNumber )
+ stk->gs_child = OffsetNumberPrev( stk->gs_child );
+ else
+ stk->gs_child = InvalidOffsetNumber;
+ }
+ break;
+ case GISTOP_SPLIT:
+ stk->gs_child = InvalidOffsetNumber;
+ break;
+ default:
+ elog(ERROR, "Bad operation in GiST scan adjust: %d", op);
+ }
+ }
stk = stk->gs_parent;
}