summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2009-06-10 18:54:16 +0000
committerTom Lane2009-06-10 18:54:16 +0000
commit51ec830b663b4b8466bbc4bdf2511cd7dc3de35b (patch)
tree03cc15a522348b60c0db1ce3bfa02efa1006d686
parente66b2519e2b6fbd82b6eb4f9ebf2aad30a4c5a22 (diff)
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.
-rw-r--r--src/backend/access/heap/heapam.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index ad11770aec..9973829654 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -93,7 +93,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;
@@ -143,7 +143,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);
@@ -1218,7 +1227,7 @@ heap_beginscan_internal(Relation relation, Snapshot snapshot,
else
scan->rs_key = NULL;
- initscan(scan, key);
+ initscan(scan, key, false);
return scan;
}
@@ -1240,7 +1249,7 @@ heap_rescan(HeapScanDesc scan,
/*
* reinitialize scan descriptor
*/
- initscan(scan, key);
+ initscan(scan, key, true);
}
/* ----------------