8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*
14
14
* INTERFACE ROUTINES
62
62
static HeapScanDesc heap_beginscan_internal (Relation relation ,
63
63
Snapshot snapshot ,
64
64
int nkeys , ScanKey key ,
65
+ bool allow_strat , bool allow_sync ,
65
66
bool is_bitmapscan );
66
67
static XLogRecPtr log_heap_update (Relation reln , Buffer oldbuf ,
67
68
ItemPointerData from , Buffer newbuf , HeapTuple newtup , bool move );
@@ -81,6 +82,9 @@ static bool HeapSatisfiesHOTUpdate(Relation relation, Bitmapset *hot_attrs,
81
82
static void
82
83
initscan (HeapScanDesc scan , ScanKey key )
83
84
{
85
+ bool allow_strat ;
86
+ bool allow_sync ;
87
+
84
88
/*
85
89
* Determine the number of blocks we have to scan.
86
90
*
@@ -99,25 +103,39 @@ initscan(HeapScanDesc scan, ScanKey key)
99
103
* strategy and enable synchronized scanning (see syncscan.c). Although
100
104
* the thresholds for these features could be different, we make them the
101
105
* 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.)
102
108
*
103
109
* During a rescan, don't make a new strategy object if we don't have to.
104
110
*/
105
- if (!scan -> rs_bitmapscan &&
106
- !scan -> rs_rd -> rd_istemp &&
111
+ if (!scan -> rs_rd -> rd_istemp &&
107
112
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 )
108
121
{
109
122
if (scan -> rs_strategy == NULL )
110
123
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 );
114
124
}
115
125
else
116
126
{
117
127
if (scan -> rs_strategy != NULL )
118
128
FreeAccessStrategy (scan -> rs_strategy );
119
129
scan -> rs_strategy = NULL ;
130
+ }
120
131
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
+ {
121
139
scan -> rs_syncscan = false;
122
140
scan -> rs_startblock = 0 ;
123
141
}
@@ -1058,29 +1076,47 @@ heap_openrv(const RangeVar *relation, LOCKMODE lockmode)
1058
1076
/* ----------------
1059
1077
* heap_beginscan - begin relation scan
1060
1078
*
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.
1065
1088
* ----------------
1066
1089
*/
1067
1090
HeapScanDesc
1068
1091
heap_beginscan (Relation relation , Snapshot snapshot ,
1069
1092
int nkeys , ScanKey key )
1070
1093
{
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);
1072
1105
}
1073
1106
1074
1107
HeapScanDesc
1075
1108
heap_beginscan_bm (Relation relation , Snapshot snapshot ,
1076
1109
int nkeys , ScanKey key )
1077
1110
{
1078
- return heap_beginscan_internal (relation , snapshot , nkeys , key , true);
1111
+ return heap_beginscan_internal (relation , snapshot , nkeys , key ,
1112
+ false, false, true);
1079
1113
}
1080
1114
1081
1115
static HeapScanDesc
1082
1116
heap_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 )
1084
1120
{
1085
1121
HeapScanDesc scan ;
1086
1122
@@ -1103,6 +1139,8 @@ heap_beginscan_internal(Relation relation, Snapshot snapshot,
1103
1139
scan -> rs_nkeys = nkeys ;
1104
1140
scan -> rs_bitmapscan = is_bitmapscan ;
1105
1141
scan -> rs_strategy = NULL ; /* set in initscan */
1142
+ scan -> rs_allow_strat = allow_strat ;
1143
+ scan -> rs_allow_sync = allow_sync ;
1106
1144
1107
1145
/*
1108
1146
* we can use page-at-a-time mode if it's an MVCC-safe snapshot
0 commit comments