Dept of second thoughts: after studying index_getnext() a bit more I realize
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 1 Nov 2009 22:30:54 +0000 (22:30 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 1 Nov 2009 22:30:54 +0000 (22:30 +0000)
that it can scribble on scan->xs_ctup.t_self while following HOT chains,
so we can't rely on that to stay valid between hashgettuple() calls.
Introduce a private variable in HashScanOpaque, instead.

src/backend/access/hash/hash.c
src/backend/access/hash/hashsearch.c
src/include/access/hash.h

index 25e601518a0cdc1a4caf746f0774f1b93403f3db..999d0cfc3184d4b1386ea3a3184ac7a67cd564ea 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.114 2009/11/01 21:25:25 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.115 2009/11/01 22:30:54 tgl Exp $
  *
  * NOTES
  *       This file contains only the public interface routines.
@@ -251,7 +251,7 @@ hashgettuple(PG_FUNCTION_ARGS)
                        IndexTuple      itup;
 
                        itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
-                       if (ItemPointerEquals(&scan->xs_ctup.t_self, &itup->t_tid))
+                       if (ItemPointerEquals(&(so->hashso_heappos), &(itup->t_tid)))
                                break;
                }
                if (offnum > maxoffnum)
@@ -304,6 +304,9 @@ hashgettuple(PG_FUNCTION_ARGS)
        if (BufferIsValid(so->hashso_curbuf))
                _hash_chgbufaccess(rel, so->hashso_curbuf, HASH_READ, HASH_NOLOCK);
 
+       /* Return current heap TID on success */
+       scan->xs_ctup.t_self = so->hashso_heappos;
+
        PG_RETURN_BOOL(res);
 }
 
@@ -345,7 +348,7 @@ hashgetbitmap(PG_FUNCTION_ARGS)
                if (add_tuple)
                {
                        /* Note we mark the tuple ID as requiring recheck */
-                       tbm_add_tuples(tbm, &scan->xs_ctup.t_self, 1, true);
+                       tbm_add_tuples(tbm, &(so->hashso_heappos), 1, true);
                        ntids++;
                }
 
@@ -375,6 +378,7 @@ hashbeginscan(PG_FUNCTION_ARGS)
        so->hashso_curbuf = InvalidBuffer;
        /* set position invalid (this will cause _hash_first call) */
        ItemPointerSetInvalid(&(so->hashso_curpos));
+       ItemPointerSetInvalid(&(so->hashso_heappos));
 
        scan->opaque = so;
 
@@ -410,6 +414,7 @@ hashrescan(PG_FUNCTION_ARGS)
 
                /* set position invalid (this will cause _hash_first call) */
                ItemPointerSetInvalid(&(so->hashso_curpos));
+               ItemPointerSetInvalid(&(so->hashso_heappos));
        }
 
        /* Update scan key, if a new one is given */
index fec2f5d78a1aa8db8166dfed13be1a6c71110651..eadd45750a7e87009daa77494d0c1dceed71af4f 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/access/hash/hashsearch.c,v 1.57 2009/06/11 14:48:53 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/hash/hashsearch.c,v 1.58 2009/11/01 22:30:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -58,7 +58,7 @@ _hash_next(IndexScanDesc scan, ScanDirection dir)
        _hash_checkpage(rel, buf, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
        page = BufferGetPage(buf);
        itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
-       scan->xs_ctup.t_self = itup->t_tid;
+       so->hashso_heappos = itup->t_tid;
 
        return true;
 }
@@ -242,7 +242,7 @@ _hash_first(IndexScanDesc scan, ScanDirection dir)
        _hash_checkpage(rel, buf, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
        page = BufferGetPage(buf);
        itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
-       scan->xs_ctup.t_self = itup->t_tid;
+       so->hashso_heappos = itup->t_tid;
 
        return true;
 }
index 100ccb9e6dbbc8816814b17d8e22d73f6685b9c9..ce5417044a291ae21f13df022915a8bca35ec4fb 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/hash.h,v 1.94 2009/11/01 21:25:25 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/hash.h,v 1.95 2009/11/01 22:30:54 tgl Exp $
  *
  * NOTES
  *             modeled after Margo Seltzer's hash implementation for unix.
@@ -99,8 +99,11 @@ typedef struct HashScanOpaqueData
         */
        Buffer          hashso_curbuf;
 
-       /* Current position of the scan */
+       /* Current position of the scan, as an index TID */
        ItemPointerData hashso_curpos;
+
+       /* Current position of the scan, as a heap TID */
+       ItemPointerData hashso_heappos;
 } HashScanOpaqueData;
 
 typedef HashScanOpaqueData *HashScanOpaque;