Dept of second thoughts: after studying index_getnext() a bit more I realize

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.
This commit is contained in:
Tom Lane 2009-11-01 22:30:54 +00:00
parent c4afdca4c2
commit 7d535ebe5b
3 changed files with 16 additions and 8 deletions

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* This file contains only the public interface routines. * This file contains only the public interface routines.
@ -251,7 +251,7 @@ hashgettuple(PG_FUNCTION_ARGS)
IndexTuple itup; IndexTuple itup;
itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum)); 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; break;
} }
if (offnum > maxoffnum) if (offnum > maxoffnum)
@ -304,6 +304,9 @@ hashgettuple(PG_FUNCTION_ARGS)
if (BufferIsValid(so->hashso_curbuf)) if (BufferIsValid(so->hashso_curbuf))
_hash_chgbufaccess(rel, so->hashso_curbuf, HASH_READ, HASH_NOLOCK); _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); PG_RETURN_BOOL(res);
} }
@ -345,7 +348,7 @@ hashgetbitmap(PG_FUNCTION_ARGS)
if (add_tuple) if (add_tuple)
{ {
/* Note we mark the tuple ID as requiring recheck */ /* 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++; ntids++;
} }
@ -375,6 +378,7 @@ hashbeginscan(PG_FUNCTION_ARGS)
so->hashso_curbuf = InvalidBuffer; so->hashso_curbuf = InvalidBuffer;
/* set position invalid (this will cause _hash_first call) */ /* set position invalid (this will cause _hash_first call) */
ItemPointerSetInvalid(&(so->hashso_curpos)); ItemPointerSetInvalid(&(so->hashso_curpos));
ItemPointerSetInvalid(&(so->hashso_heappos));
scan->opaque = so; scan->opaque = so;
@ -410,6 +414,7 @@ hashrescan(PG_FUNCTION_ARGS)
/* set position invalid (this will cause _hash_first call) */ /* set position invalid (this will cause _hash_first call) */
ItemPointerSetInvalid(&(so->hashso_curpos)); ItemPointerSetInvalid(&(so->hashso_curpos));
ItemPointerSetInvalid(&(so->hashso_heappos));
} }
/* Update scan key, if a new one is given */ /* Update scan key, if a new one is given */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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); _hash_checkpage(rel, buf, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
page = BufferGetPage(buf); page = BufferGetPage(buf);
itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum)); itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
scan->xs_ctup.t_self = itup->t_tid; so->hashso_heappos = itup->t_tid;
return true; return true;
} }
@ -242,7 +242,7 @@ _hash_first(IndexScanDesc scan, ScanDirection dir)
_hash_checkpage(rel, buf, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE); _hash_checkpage(rel, buf, LH_BUCKET_PAGE | LH_OVERFLOW_PAGE);
page = BufferGetPage(buf); page = BufferGetPage(buf);
itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum)); itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
scan->xs_ctup.t_self = itup->t_tid; so->hashso_heappos = itup->t_tid;
return true; return true;
} }

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* modeled after Margo Seltzer's hash implementation for unix. * modeled after Margo Seltzer's hash implementation for unix.
@ -99,8 +99,11 @@ typedef struct HashScanOpaqueData
*/ */
Buffer hashso_curbuf; Buffer hashso_curbuf;
/* Current position of the scan */ /* Current position of the scan, as an index TID */
ItemPointerData hashso_curpos; ItemPointerData hashso_curpos;
/* Current position of the scan, as a heap TID */
ItemPointerData hashso_heappos;
} HashScanOpaqueData; } HashScanOpaqueData;
typedef HashScanOpaqueData *HashScanOpaque; typedef HashScanOpaqueData *HashScanOpaque;