From 8882a467f0d159410cd04b434813f5828089515c Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 10 Jun 2009 18:54:23 +0000 Subject: [PATCH] Keep rs_startblock the same during heap_rescan, so that a rescan of a SeqScan node starts from the same place as the first scan did. This avoids surprising behavior of scrollable and WITH HOLD cursors, as seen in Mark Kirkwood's bug report of yesterday. It's not entirely clear whether a rescan should be forced to drop out of the syncscan mode, but for the moment I left the code behaving the same on that point. Any change there would only be a performance and not a correctness issue, anyway. Back-patch to 8.3, since the unstable behavior was created by the syncscan patch. --- src/backend/access/heap/heapam.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 9fcb1fe397..566e431cca 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.249.2.4 2008/12/16 16:26:14 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.249.2.5 2009/06/10 18:54:23 tgl Exp $ * * * INTERFACE ROUTINES @@ -84,7 +84,7 @@ static bool HeapSatisfiesHOTUpdate(Relation relation, Bitmapset *hot_attrs, * ---------------- */ static void -initscan(HeapScanDesc scan, ScanKey key) +initscan(HeapScanDesc scan, ScanKey key, bool is_rescan) { bool allow_strat; bool allow_sync; @@ -134,7 +134,16 @@ initscan(HeapScanDesc scan, ScanKey key) scan->rs_strategy = NULL; } - if (allow_sync && synchronize_seqscans) + if (is_rescan) + { + /* + * If rescan, keep the previous startblock setting so that rewinding + * a cursor doesn't generate surprising results. Reset the syncscan + * setting, though. + */ + scan->rs_syncscan = (allow_sync && synchronize_seqscans); + } + else if (allow_sync && synchronize_seqscans) { scan->rs_syncscan = true; scan->rs_startblock = ss_get_location(scan->rs_rd, scan->rs_nblocks); @@ -1177,7 +1186,7 @@ heap_beginscan_internal(Relation relation, Snapshot snapshot, else scan->rs_key = NULL; - initscan(scan, key); + initscan(scan, key, false); return scan; } @@ -1199,7 +1208,7 @@ heap_rescan(HeapScanDesc scan, /* * reinitialize scan descriptor */ - initscan(scan, key); + initscan(scan, key, true); } /* ---------------- -- 2.50.1