postgres.git / summary / log / commit / refs

commit    61dd4185ffb034a22b4b40425d56fe37e7178488
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Wed Jun 10 18:54:16 2009 +0000
First released in: 8.4.0, 8.3.8

    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 272fb32c58f..1f6edf6cafa 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.275 2009/05/12 16:43:32 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.276 2009/06/10 18:54:16 tgl Exp $ * * * INTERFACE ROUTINES @@ -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); } /* ---------------- [parent: 2ef8c1acfd5a]