]> granicus.if.org Git - postgresql/commitdiff
Fix missing rows in query
authorTeodor Sigaev <teodor@sigaev.ru>
Tue, 30 Aug 2005 08:36:52 +0000 (08:36 +0000)
committerTeodor Sigaev <teodor@sigaev.ru>
Tue, 30 Aug 2005 08:36:52 +0000 (08:36 +0000)
update a=.. where a... with GiST index on column 'a'
Backpatch from 8.0 branch

src/backend/access/gist/gist.c
src/backend/access/gist/gistget.c
src/backend/access/gist/gistscan.c

index 2f990ec05ed82722ec82b4c413d37c2fcd526af2..4d595ca9877f629ec8bf22958bf5dd554cbe401a 100644 (file)
@@ -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);
 
index 596c11e41e80fecd20c69f0af3145fbd2daa5ed0..63b09a961f471708819ac41937ca2c3be3799d1a 100644 (file)
@@ -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);
 
index 790048aef38a778eedf629647c154f09d9727d9d..9616d4d19c267fcd63d25c7c6d3b15c0d70fd7b6 100644 (file)
@@ -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;
        }