88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.247 2008/01/01 19:45:46 momjian Exp $
11+ * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.248 2008/01/14 01:39:09 tgl Exp $
1212 *
1313 *
1414 * INTERFACE ROUTINES
6262static HeapScanDesc heap_beginscan_internal (Relation relation ,
6363 Snapshot snapshot ,
6464 int nkeys , ScanKey key ,
65+ bool allow_strat , bool allow_sync ,
6566 bool is_bitmapscan );
6667static XLogRecPtr log_heap_update (Relation reln , Buffer oldbuf ,
6768 ItemPointerData from , Buffer newbuf , HeapTuple newtup , bool move );
@@ -81,6 +82,9 @@ static bool HeapSatisfiesHOTUpdate(Relation relation, Bitmapset *hot_attrs,
8182static void
8283initscan (HeapScanDesc scan , ScanKey key )
8384{
85+ bool allow_strat ;
86+ bool allow_sync ;
87+
8488 /*
8589 * Determine the number of blocks we have to scan.
8690 *
@@ -99,25 +103,39 @@ initscan(HeapScanDesc scan, ScanKey key)
99103 * strategy and enable synchronized scanning (see syncscan.c). Although
100104 * the thresholds for these features could be different, we make them the
101105 * same so that there are only two behaviors to tune rather than four.
106+ * (However, some callers need to be able to disable one or both of
107+ * these behaviors, independently of the size of the table.)
102108 *
103109 * During a rescan, don't make a new strategy object if we don't have to.
104110 */
105- if (!scan -> rs_bitmapscan &&
106- !scan -> rs_rd -> rd_istemp &&
111+ if (!scan -> rs_rd -> rd_istemp &&
107112 scan -> rs_nblocks > NBuffers / 4 )
113+ {
114+ allow_strat = scan -> rs_allow_strat ;
115+ allow_sync = scan -> rs_allow_sync ;
116+ }
117+ else
118+ allow_strat = allow_sync = false;
119+
120+ if (allow_strat )
108121 {
109122 if (scan -> rs_strategy == NULL )
110123 scan -> rs_strategy = GetAccessStrategy (BAS_BULKREAD );
111-
112- scan -> rs_syncscan = true;
113- scan -> rs_startblock = ss_get_location (scan -> rs_rd , scan -> rs_nblocks );
114124 }
115125 else
116126 {
117127 if (scan -> rs_strategy != NULL )
118128 FreeAccessStrategy (scan -> rs_strategy );
119129 scan -> rs_strategy = NULL ;
130+ }
120131
132+ if (allow_sync )
133+ {
134+ scan -> rs_syncscan = true;
135+ scan -> rs_startblock = ss_get_location (scan -> rs_rd , scan -> rs_nblocks );
136+ }
137+ else
138+ {
121139 scan -> rs_syncscan = false;
122140 scan -> rs_startblock = 0 ;
123141 }
@@ -1058,29 +1076,47 @@ heap_openrv(const RangeVar *relation, LOCKMODE lockmode)
10581076/* ----------------
10591077 * heap_beginscan - begin relation scan
10601078 *
1061- * heap_beginscan_bm is an alternative entry point for setting up a HeapScanDesc
1062- * for a bitmap heap scan. Although that scan technology is really quite
1063- * unlike a standard seqscan, there is just enough commonality to make it
1064- * worth using the same data structure.
1079+ * heap_beginscan_strat offers an extended API that lets the caller control
1080+ * whether a nondefault buffer access strategy can be used, and whether
1081+ * syncscan can be chosen (possibly resulting in the scan not starting from
1082+ * block zero). Both of these default to TRUE with plain heap_beginscan.
1083+ *
1084+ * heap_beginscan_bm is an alternative entry point for setting up a
1085+ * HeapScanDesc for a bitmap heap scan. Although that scan technology is
1086+ * really quite unlike a standard seqscan, there is just enough commonality
1087+ * to make it worth using the same data structure.
10651088 * ----------------
10661089 */
10671090HeapScanDesc
10681091heap_beginscan (Relation relation , Snapshot snapshot ,
10691092 int nkeys , ScanKey key )
10701093{
1071- return heap_beginscan_internal (relation , snapshot , nkeys , key , false);
1094+ return heap_beginscan_internal (relation , snapshot , nkeys , key ,
1095+ true, true, false);
1096+ }
1097+
1098+ HeapScanDesc
1099+ heap_beginscan_strat (Relation relation , Snapshot snapshot ,
1100+ int nkeys , ScanKey key ,
1101+ bool allow_strat , bool allow_sync )
1102+ {
1103+ return heap_beginscan_internal (relation , snapshot , nkeys , key ,
1104+ allow_strat , allow_sync , false);
10721105}
10731106
10741107HeapScanDesc
10751108heap_beginscan_bm (Relation relation , Snapshot snapshot ,
10761109 int nkeys , ScanKey key )
10771110{
1078- return heap_beginscan_internal (relation , snapshot , nkeys , key , true);
1111+ return heap_beginscan_internal (relation , snapshot , nkeys , key ,
1112+ false, false, true);
10791113}
10801114
10811115static HeapScanDesc
10821116heap_beginscan_internal (Relation relation , Snapshot snapshot ,
1083- int nkeys , ScanKey key , bool is_bitmapscan )
1117+ int nkeys , ScanKey key ,
1118+ bool allow_strat , bool allow_sync ,
1119+ bool is_bitmapscan )
10841120{
10851121 HeapScanDesc scan ;
10861122
@@ -1103,6 +1139,8 @@ heap_beginscan_internal(Relation relation, Snapshot snapshot,
11031139 scan -> rs_nkeys = nkeys ;
11041140 scan -> rs_bitmapscan = is_bitmapscan ;
11051141 scan -> rs_strategy = NULL ; /* set in initscan */
1142+ scan -> rs_allow_strat = allow_strat ;
1143+ scan -> rs_allow_sync = allow_sync ;
11061144
11071145 /*
11081146 * we can use page-at-a-time mode if it's an MVCC-safe snapshot
0 commit comments